Last active
April 24, 2018 09:10
-
-
Save joneskoo/bf5a75afe819dad11346 to your computer and use it in GitHub Desktop.
Django: Reusable model filtering: Using QuerySet.as_manager() properly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.