How to use and create Custom Model Manager in Django for Beginners
In Django, Model Managers are classes that act as the interface between Django models and the database. A Model can have any number of managers and using these managers we can extend the functionality of the model.
Table of Contents
Introduction
An Introduction to Django Model Managers, we’ll start from the default model manager and then go through creating and customizing model managers.
In this post, we’ll take the example of a BlogModel
and then create a custom model manager for it.
Create a Model
The first step is to create an app and name it blogs
and make BlogModel
in file models.py
.
from datetime import datetime from django.db import models from django.contrib.auth.models import User class BlogModel(models.Model): BLOG_STATUS = ( ('PUBLISH', 'Publish'), ('DRAFT', 'Draft'), ) blog_id = models.AutoField(primary_key=True) user = models.ForeignKey( User, on_delete=models.CASCADE, related_name='blogs' ) title = models.CharField(max_length=255) content = models.TextField(blank=True, null=True) status = models.CharField(max_length=7, choices=BLOG_STATUS) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta(): db_table = 'blogs' verbose_name = 'Blog' verbose_name_plural = 'Blogs' def __str__(self): return self.title
In BlogModel
field user
shares ForeignKey
relationship with Django’s built-in AUTH_USER_MODEL
.
Default Model Manager
If you haven’t specified any model manager to your models then Django implicitly adds a default model manager to your model. In this case model BlogModel
does not have any specified model managers in such case objects
will be assigned as model managers.
Anytime fetching, updating, or deleting rows are done through object
model managers.
Some examples are shown below
from blogs.models import BlogModel blog_list = BlogModel.objects.all() blog_list = BlogModel.objects.filter(user=5)
If you want to use other model manager name insisted objects
then you can also do that by assigning the default model manager to name with which
you would like to access the example shown below.
#in models.py class BlogModel(models.Model): ... ... ... custom_objects = models.Manager() #in python manage.py shell >>> from datetime import datetime >>> from django.db import models >>> from django.contrib.auth.models import User >>> from blogs.models import BlogModel >>> blog_list = BlogModel.custom_objects.all() >>> blog_list , , ...(remaining elements truncated)...']>

Django list querysets using default model manager
And now if we try to retrieve data using objects
then Django will throw AttributeError
exception.
>>> blog_list = BlogModel.objects.all() Traceback (most recent call last): File "/usr/lib/python3.5/code.py", line 91, in runcode exec(code, self.locals) File "", line 1, in AttributeError: type object 'BlogModel' has no attribute 'objects'

Django throws AttributeError when called to the wrong model manager.
Create Customer Model Manager
Custom models managers can be created by inheriting Django’s models.Manager
which also is a default manager and provides much functionality related to querying querysets.
In our app blogs
create a new file and name it managers.py
and in that file import from django.db import models
as shown below.
from django.db import models class BlogModelManager(models.Manager): def get_queryset(self): queryset = super().get_queryset() return queryset def with_all_users(self): # returns blogs with inner joining auth user model queryset = self.get_queryset() queryset = queryset.select_related('user') return queryset def with_order_by_user_first_name(self, type="ASC"): queryset = self.with_all_users() field = 'user__first_name' if type=='DESC': field = '-user__first_name' queryset = queryset.order_by(field) return queryset
Now we have created our custom model manager its all it to BlogModel
.
from blogs.managers import (BlogModelManager, ) class BlogModel(models.Model): ... ... ... objects = BlogModelManager();
In BlogModelManager
we have specified three methods the first get_queryset(self)
method is the built-in method which returns the queryset.
with_all_users(self)
method calls get_queryset()
and also makes inner join with user
which is Django’s default user model.
The queryset method select_related()
creates an inner join and while calling this method the query will be like below.
SELECT `blogs`.`blog_id`, `blogs`.`user_id`, `blogs`.`title`, `blogs`.`content`, `blogs`.`status`, `blogs`.`created_at`, `blogs`.`updated_at`, `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `blogs` INNER JOIN `auth_user` ON (`blogs`.`user_id` = `auth_user`.`id`)
The method with_order_by_user_first_name(self, type="ASC")
will order the queryset by field first_name
of Django’s default auth user model.
This method will execute as the below query.
SELECT `blogs`.`blog_id`, `blogs`.`user_id`, `blogs`.`title`, `blogs`.`content`, `blogs`.`status`, `blogs`.`created_at`, `blogs`.`updated_at`, `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `blogs` INNER JOIN `auth_user` ON (`blogs`.`user_id` = `auth_user`.`id`) ORDER BY `auth_user`.`first_name` ASC
In python shell, you can call these methods shown below.
blogs = BlogModel.objects.with_all_users() blogs_ordered_by_fname = BlogModel.objects.with_order_by_user_first_name(type="DESC")
Conclusion
We have come to the end of our post on How to use and create Custom Model Manager in Django for Beginners. If you like our content then please do share it and comment to clarify your doubts. We thank you from bottom of our heart.
Related Posts
- Learn Django Signals | The Quickest and Easiest Way for Beginners
- Django Custom Context Preprocessors – Share Data across all Templates




