Show furnitures in a different way considering django principle 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:

&lt;h1&gt;Newly Arrival&lt;/h1&gt;
{% for new_furniture in furnitures %}
  {{ new_furniture.name }}
{% endfor %}

&lt;h1&gt;Featured&lt;/h1&gt;
{% for featured_furniture in featured %}
  {{ featured_furniture.name }}
{% endfor %}
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.