In Django, can you add a method to querysets?

Paul D. Waite picture Paul D. Waite · Jan 2, 2011 · Viewed 15k times · Source

In Django, if I have a model class, e.g.

from django.db import models

class Transaction(models.Model):
    ...

then if I want to add methods to the model, to store e.g. reasonably complex filters, I can add a custom model manager, e.g.

class TransactionManager(models.Manager):

    def reasonably_complex_filter(self):
        return self.get_query_set().filter(...)


class Transaction(models.Model):
    objects = TransactionManager()

And then I can do:

>>> Transaction.objects.reasonably_complex_filter()

Is there any way I can add a custom method that can be chained to the end of a query set from the model?

i.e. add the custom method in such a way that I can do this:

>>> Transaction.objects.filter(...).reasonably_complex_filter()

Answer

Burhan Khalid picture Burhan Khalid · Oct 30, 2014

As of django 1.7, the ability to use a query set as a manager was added:

class PersonQuerySet(models.QuerySet):
    def authors(self):
        return self.filter(role='A')

    def editors(self):
        return self.filter(role='E')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=(('A', _('Author')),
                                                   ('E', _('Editor'))))
    people = PersonQuerySet.as_manager()

Resulting the following:

Person.people.authors(last_name='Dahl')

In addition, the ability to add custom lookups was also added.