python / intermediate
Snippet
Django Custom Model Manager and QuerySet Methods
This pattern shows how to create reusable QuerySet methods by chaining them through a custom Manager. The PublishedQuerySet class encapsulates query logic in reusable methods that can be chained together. The ArticleManager delegates to this QuerySet while exposing a clean API. This approach keeps query logic modular and testable.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from django.db import modelsclass PublishedQuerySet(models.QuerySet):def published(self):return self.filter(status='published')def in_date_range(self, start, end):return self.filter(published_date__range=[start, end])def by_author(self, author):return self.filter(author=author)def with_min_views(self, min_views):return self.filter(view_count__gte=min_views)class ArticleManager(models.Manager):def get_queryset(self):return PublishedQuerySet(self.model, using=self._db)def published(self):return self.get_queryset().published()def with_min_views(self, min_views):return self.get_queryset().with_min_views(min_views)class Article(models.Model):title = models.CharField(max_length=200)author = models.ForeignKey(User, on_delete=models.CASCADE)status = models.CharField(max_length=20, default='draft')published_date = models.DateTimeField(null=True)view_count = models.IntegerField(default=0)content = models.TextField()objects = ArticleManager()class Meta:ordering = ['-published_date']
django
Breakdown
1
class PublishedQuerySet(models.QuerySet):
Define custom QuerySet class inheriting from models.QuerySet
2
def published(self):
Filter method returning only published articles
3
return self.filter(status='published')
Chain filter onto the QuerySet and return it
4
def in_date_range(self, start, end):
Date range filter method with start and end parameters
5
def by_author(self, author):
Method to filter articles by specific author instance
6
class ArticleManager(models.Manager):
Custom manager class inheriting from models.Manager
7
return PublishedQuerySet(self.model, using=self._db)
Override get_queryset to return custom QuerySet with proper database routing
8
objects = ArticleManager()
Assign custom manager as the default manager for the model