I want in my homepage to show the furnitures items in a following way:
Newly Arrived Furnitures(upto 10)
Featured Furnitures
Free shipping Furnitures (upto 10)
For this I tried to go with the principle of Fat Models, Thin View
. Here is my code
class FurnitureQuerySet(models.QuerySet):
def active(self):
return self.filter(is_active=True)
def featured(self):
return self.active().filter(is_featured=True)
def new_arrival(self, max_furnitures):
return self.active().order_by('-id')[:max_furnitures]
def free_shipping(self, max_furnitures):
return self.active().filter(is_free_shipping=True)[:max_furnitures]
class FurnitureManager(models.Manager):
def get_queryset(self):
return FurnitureQuerySet(self.model, using=self._db)
def all(self):
return self.get_queryset().active()
def featured(self):
return self.get_queryset().featured()
def new_arrival(self, max_furnitures):
return self.get_queryset().new_arrival(max_furnitures)
def free_shipping(self, max_furnitures):
return self.get_queryset().free_shipping(max_furnitures)
def get_by_id(self, slug):
qs = self.get_queryset().filter(slug=slug)
if qs.count() == 1:
return qs.first()
return None
class Furniture(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
manufacturer = models.ForeignKey(Manufacturer, blank=True, null=True)
slug = models.SlugField(max_length=200, unique=True)
is_active = models.BooleanField(
default=True, help_text='Furniture is available for listing and sale')
is_featured = models.BooleanField(
default=False, help_text='Promote this furniture on main pages')
is_free_shipping = models.BooleanField(
default=False, help_text='No shipping charges')
timestamp = models.DateTimeField(auto_now_add=True)
objects = FurnitureManager()
def home(request):
categories = Category.objects.root_nodes()
furnitures = Furniture.objects.new_arrival(10)
featured_furnitures = Furniture.objects.featured()
shipping_free_furnitures = Furniture.objects.free_shipping(10)
context = {
'categories': categories,
'furnitures': furnitures,
'featured': featured_furnitures,
'shipping_free': shipping_free_furnitures,
}
return render(request, 'home.html', context)
The template will be:
<h1>Newly Arrival</h1>
{% for new_furniture in furnitures %}
{{ new_furniture.name }}
{% endfor %}
<h1>Featured</h1>
{% for featured_furniture in featured %}
{{ featured_furniture.name }}
{% endfor %}
1 Answer 1
Do take care to run flake8
over the source, and follow its advice.
Array slicing [:max_furnitures]
is idiomatic and nice. But if you have a thousand or a million items, you will prefer to use SQL limit
, so you don't retrieve a ton of items from the DB only to discard them. You will get a different execution plan from the backend DB if you expose limit 10
to its query optimizer.
I see four different max_furnitures parameters. Now maybe this is perfectly nice and we prefer to leave it as is. But also consider introducing it as an attribute used by constructor.
Looks good.
Ship it.