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 | from datetime import datetime
from django.db import models
from django.db.models.query import QuerySet
class PostMixin(object):
def by_author(self, user):
return self.filter(user=user)
def published(self):
return self.filter(published__lte=datetime.now())
class PostQuerySet(QuerySet, PostMixin):
pass
class PostManager(models.Manager, PostMixin):
def get_query_set(self):
return PostQuerySet(self.model, using=self._db)
class Post(models.Model):
user = models.ForeignKey(User)
published = models.DateTimeField()
objects = PostManager()
Post.objects.by_author(user=request.user).published()
|
More like this
- Easier custom Model Manager Chaining by gsakkis 2 years, 10 months ago
- QuerySetManager - easily add new QuerySet methods using a Model inner class by simon 5 years ago
- Easier chainability with custom QuerySets by bendavis78 1 year, 2 months ago
- Custom managers with chainable filters by itavor 5 years, 4 months ago
- TaggedManager and TaggedQuerySet with chainable tagged() methods implemented with django-tagging by fish2000 3 years, 2 months ago
Comments
I have started using this pattern myself (I suggested the author upload it here) and can confirm its awesomeness.
I've seen many attempts at queryset chaining in Django, and they are invariably complex and frequently quite brittle. This approach is astoundingly simple and easy to use.
My only complaint is that there's a tad bit more excess boilerplate code to get it working than would be ideal. The purpose of the boilerplate is probably opaque to someone stumbling upon it and not knowing what it's for.
#
""" My only complaint is that there's a tad bit more excess boilerplate code to get it working than would be ideal. """
Check out #2117 for a no-boilerplate extension of the same idea.
#