Good Code
The good version names the visibility rule once and lets views ask for the query they need.
Lesson 04
Put common query rules in QuerySet or manager methods so views do not repeat domain filters.
from django.db import models
class ReviewQuerySet(models.QuerySet):
# Name the visibility rule once so views do not copy filters.
def visible_to(self, user):
base = self.filter(deleted_at__isnull=True)
if user.is_staff:
return base
return base.filter(status=Review.Status.PUBLISHED)
def with_author(self):
# Keep relationship loading behind a readable query name.
return self.select_related("author")
class Review(models.Model):
objects = ReviewQuerySet.as_manager()
def review_list(request):
reviews = Review.objects.visible_to(request.user).with_author()
return render(request, "reviews/list.html", {"reviews": reviews})# Duplicated filters drift when the rule changes.
def review_list(request):
reviews = Review.objects.filter(
deleted_at__isnull=True,
status="published",
).select_related("author")
return render(request, "reviews/list.html", {"reviews": reviews})
def review_feed(request):
reviews = Review.objects.filter(
deleted_at__isnull=True,
status="published",
).order_by("-published_at")
return render(request, "reviews/feed.html", {"reviews": reviews})The good version names the visibility rule once and lets views ask for the query they need.
The bad version repeats filters in multiple views. When the visibility rule changes, one path can easily drift.