Definitive Guide for Adding Custom Model Managers in Django
Published: 2020-04-30 07:22:59

---
description: Want to know how Django managers can help you maintain your code? Here’s a definitive guide for Django managers and how to implement them the right way.
---
![Django managers](https://www.botreetechnologies.com/blog/wp-content/uploads/2020/04/definitive-guide-for-django-managers.png)

##What is a manager?

A manager is an interface through which database query operations are provided to django models. It is some kind of 'gate' between application and database

Hence,  there exists at least one manager for every model in a django application.

{% gist https://gist.github.com/MeetParikh01/800ba28f93edc4546f6c741a2bbc6589 %}

In this case, django adds the default manager with the name **objects** is used.

We can even rename the manager's name on a pre model basis . So let us consider a Student Model.

{% gist https://gist.github.com/MeetParikh01/b50eec103c2fb9a43cea9393193fdc34 %}

Here, we can access Student model queries like  **Student.student.all()** where **student** is the manager's name.

###Benefits of using managers in your code:

* Clean code.
* Efficient code.
* Maintainable code.
* Writing common query code for the model which are reusable. (DRY rule i.e. Don’t repeat yourself)

###How to write custom managers?

A custom Manager is created by extending a base **Manager** class  in a particular model and by instantiating  the created custom manager within the model. 

We have created  a custom manager by name **StudentManager** and thus, our managers looks like -

{% gist https://gist.github.com/MeetParikh01/74cfdf8ec767a9dac910617c9d850d2a %}

Thus, to access a Student Model with different queries defined in the StudentManager, it can be done like this -

{% gist https://gist.github.com/MeetParikh01/0e941521d9bbf95ab70fafbb8bd8492b %}

Though in the given examples we have returned the queryset,  one can return anything like a list, dictionary, attribute value etc.

###Modifying a manager initial QuerySet 

A Manager’s base QuerySet returns all objects in the system. For example, in our **Student** Model we get all the objects using **Student.student.all()** but if we want to modify the initial queryset  then we need to override a **Manager’s** base **QuerySet** by overriding the **manager.get_queryset()** method. **get_queryset()** should return a **QuerySet** with the properties we require.

So here we have created two managers for our **Student** Model by name **MaleManager** and **FemaleManager** and instantiated them by name **male** and **female**, so our **MaleManager** and **FemaleManager** looks as and their access like.

{% gist https://gist.github.com/MeetParikh01/3f4ebf3e36a7d9469a10dfce91fa3071 %}

###ProjectStatusSerializerCalling custom QuerySet method from the manager

Most of the methods from the standard QuerySet are directly accessible from the manager but if we want to add methods that need to be accessible as attributes then we need to define Custom Queryset.

We need to do this because the methods defined in the manager are not chainable.

For example, in our **StudentManager** we have a method by name **get_males()** if we try to chain it with **get_students_age_less_or_equal()** then it will throw error like this -

{% gist https://gist.github.com/MeetParikh01/16153a9bc5c74dde532142ece5899c37 %}

So, to make it work, we will define our own QuerySets Method  and using that method in a seperate manager named as **StudentModifyManager**

{% gist https://gist.github.com/MeetParikh01/4f67d1164352c1f7c861b83334c39df4 %}

Now as in our models we have instantiate our **StudentModifyManager** as **modify** named object, so we can use the chainable methods as -

{% gist https://gist.github.com/MeetParikh01/9022f184a0841c4a491875973d954fc2 %}

###Creating a manager with QuerySet Methods.

While calling  **StudentQuerySet** Methods, we need to **duplicate** its methods in our **StudentModifyManager**. If we don’t want to duplicate those methods then we can create a manage with queryset methods.

In our **Student** Model we have created a manager with object **query as
query** = **StudentQuerySet.as_manager()**

Now, we can use that manager as **Student.query.male().get_sem3_students()** and can get output according to it.

Thus, here the **StudentQuerySet.as_manager()** is virtually identical to the **StudentModifyManager** .

**from_queryset** method: classmethod from_queryset(queryset_class)

If we want the custom **Manager** and the custom **QuerySet** for the advanced usage then it can be done by **Manager.from_queryset()** which returns the subclass of the base class with a copy of the custom Queryset methods.

So in our Student model, we have done it by creating a **custom** object in the model as 

**custom = StudentModifyManager.from_queryset(StudentQuerySet)()**  where the **StudentModifyManager** is our custom Manager and the **StudentQuerySet** is our custom QuerySet 

Now looking at the output in our shell -

{% gist https://gist.github.com/MeetParikh01/40222afd3b35d88094136c200664e0be %}

###Conclusion

Django managers ensure that you write code which is easily maintained and adhere to the DRY principle. They allow keeping queries at a centralized location so that all the queries come from a single location instead of flying in from everywhere.

###[Click here for more details…](https://www.botreetechnologies.com/django-development)