I'm defining a model in Django. I want to define a few custom methods for its QuerySet
objects. (i.e. I want to define custom ways to filter instances of that object, in a way peculiar only to that model.)
Now, I could define those on the Manager
, but then these methods will be accessible only on the Manager
and not on any single QuerySet
which is the result of any kind of filtering on that model.
So: How do I give the QuerySet
objects of my model custom filtering methods?
If you need filter chaining extend Queryset
.
One example from my current project:
from django.db import models
from django.db.models.query import QuerySet
class MemberQuerySet(QuerySet):
def in_group(self, group):
return self.filter(group_set__pk=group.pk)
def not_in_group(self, group):
return self.exclude(groups_set__pk=group.pk)
class MemberManager(models.Manager):
def get_queryset(self):
return MemberQuerySet(self.model, using=self._db)
def in_group(self, group):
return self.get_queryset().in_group(group)
def not_in_group(self, group):
return self.get_queryset().not_in_group(group)
class Member(models.Model):
# ...
objects = MemberManager()
With this you can do:
Member.objects.in_group(one_group).not_in_group(another_group)
If you don't need filter chaining a manager with custom methods would be enough. That's quite well covered in the docs.
This snippet seems nice for faster QuerySet
plug-in, but it is old (4 years) and I've never tried it.
Resurrecting this to offer a better, cleaner way to do this.
From at least django 1.8 (not tested on anything earlier..it may or may not work, not sure when this API was introduced), there's a much nicer way to do this...
from django.db import models
from django.db.models.query import QuerySet
class MemberQuerySet(QuerySet):
def in_group(self, group):
return self.filter(group_set__pk=group.pk)
def not_in_group(self, group):
return self.exclude(group_set__pk=group.pk)
# etc..
class Member(models.Model):
# fields..
objects = MemberQuerySet.as_manager()
Then you can do this..
Member.objects.in_group(group1).not_in_group(group2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With