Django: Custom Manager With Chainable QuerySets

This tutorial will teach you how you can create an interface to your Django models which allows you to chain queries so that you can do to the following:

from myapp.models import Tutorial
# Perform a query from scratch:
Tutorial.objects.all().written_by(author_id=1).published(True)

# You would also be able to do something like this:
auther.tutorial_set.all().published(True)

We acheive this by using a combination of a QuerySet and a Manager.

Our QuerySet

class TutorialQuerySet(models.QuerySet):
    def written_by(self, author_id):
        return self.filter(author_id=author_id)
    
    def published(self, is_published=True):
    	return self.filter(is_published=is_published)
      

Our Manager:

class TutorialManager(models.Manager):
    pass

And finally, we need to set the manager on our model such that it mixes in our QuerySet:

models.py

class Tutorial(models.Model):

	...   
	objects = TutorialManager.from_queryset(TutorialQuerySet)()
    

And that's it! You can now chain your queries.

Resources: