Skip to content

Instantly share code, notes, and snippets.

@joneskoo
Last active April 24, 2018 09:10
Show Gist options
  • Save joneskoo/bf5a75afe819dad11346 to your computer and use it in GitHub Desktop.
Save joneskoo/bf5a75afe819dad11346 to your computer and use it in GitHub Desktop.
Django: Reusable model filtering: Using QuerySet.as_manager() properly
# http://www.dabapps.com/blog/higher-level-query-api-django-orm/
# Converted to use Django 1.8 QuerySet.as_manager()
# We inherit custom QuerySet to define new methods
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def high_priority(self):
return self.filter(priority=1)
class Todo(models.Model):
content = models.CharField(max_length=100)
# other fields go here..
objects = TodoQuerySet.as_manager() # Activate custom QuerySet
# Now that we have a custom manager on Todo, we can chain filters
# e.g.
all = Todo.objects.all()
incomplete = Todo.objects.incomplete()
incomplete_hp = Todo.objects.incomplete().high_priority()
# This is super useful because it allows removing .filter(XXXXXXX)
# from View and improves maintainability in complex projects a lot.
@joneskoo
Copy link
Author

joneskoo commented Oct 4, 2015

The DabApps Ltd. article on inheriting QuerySet is great. It's written before Django got the .as_manager() method for QuerySet though and needs update. I'd use something like this gist instead.

The Django documentation Creating Manager with QuerySet methods example is not sufficient to explain this.

This example should be covered also by Django tutorial. In my opinion it's a best practice to avoid writing complex filters in views - they belong to models like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment