Custom Managers and QuerySet Methods in Django

July 10, 2021, 12:19 p.m.

This tutorial will show you how to work with managers in Django, you will also see how we can extract managers straight from the QuerySet by using .as_manager() method.

What is a model manager

Django documentation says:

A Manager is the interface through which database query operations are provided to Django models.

When we retrieve objects from the database, behind the scenes we are constructing a QuerySet via a Manager on our model class.

Default Manager

Example:

>>> Article.objects.all()

objects here is our default manager. By default, Django adds a Manager with the name objects to every Django model class.

Calling custom QuerySet methods from the manager

The example below will allow you to call both authors() and editors() which are our custom QuerySet methods directly from the manager Person.people.



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

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



class PersonManager(models.Manager):
    def get_queryset(self):
        return PersonQuerySet(self.model, using=self._db)

    def authors(self):
        return self.get_queryset().authors()

    def editors(self):
        return self.get_queryset().editors()


class Person(models.Model):

    ROLES = (

       ('A',   'Author' ),
       ('E',   'Editor' ),

    )

    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=ROLES, default="A" )
    people = PersonManager()

 

The above approach works fine but we have repeated code which is not good, next example shows the same example but it uses as_manager() method which makes the code a lot cleaner.

REMOVING DUPLICATE CODE

Here we extracted the manager straight from the QuerySet , this approach helps us stop code repetition by using the as_manager() method.



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

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


class Person(models.Model):

    ROLES = (

       ('A',   'Author' ),
       ('E',   'Editor' ),

     )

    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=ROLES, default="A" )
    people = PersonQuerySet.as_manager()

HOW TO USE THE MANAGER

  • Person.people.editors()

  • Person.people.authors()

Advantages of model managers

  • Readability - when we use model managers, we reduce complexity in our model.

  • Ease of maintenance - model managers make our model simple and readable which also leads to ease of maintenance in the long run.

Get code on GitHub here : django-managers-example

RESOURCES

Header photo by Kelly Sikkema on unsplash

Django managers tutorial

Keep Learning