A manager is an interface through which database query operations are provided to Django models. At least one Manager
exists for every model in a Django application, objects
is the default manager of every model that retrieves all objects in the database.
However, one model can have multiple model managers, we can also build our own custom model managers by extending the base manager class.
In this article, we will learn how to create custom model managers in Django.
Creating Custom Model Managers
In this article, we will build a model manager for a blog application.
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
def __str__(self):
return self.title
As we know objects
is the default model manager for every model, therefore Post.objects.all()
will return all post objects.
The objects
method is capable of doing all basic QuerySets then why would we need a custom model manager?
There are two reasons you might want to customize a Manager -
- To add extra Manager methods.
- To modify the initial QuerySet the Manager returns.
Let's create a model manager to retrieve all the published posts.
Using the objects
manager published posts can be retrieved with the following query.
In : Post.objects.filter(active=True)
Out: <QuerySet [<Post: Fourth Post>, <Post: First post>]>
We will build a custom model manager called published
to retrieve the published posts.
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager, self).get_queryset().filter(active=True)
class Post(models.Model):
......
# Model managers
objects = models.Manager() # The default manager.
published = PublishedManager() # Our custom manager.
def __str__(self):
return self.title
Now we can retrieve posts with the custom model manager as follows.
In [2]: Post.published.all()
Out[2]: <QuerySet [<Post: First post>, <Post: Fourth Post>]>
In [3]: Post.objects.filter(active= True)
Out[3]: <QuerySet [<Post: First post>, <Post: Fourth Post>]>
The custom model manager's get_queryset()
returns a QuerySet object, thus you can use filter()
, exclude()
and all the other QuerySet methods on it.
In : Post.published.count()
Out: 2
To explore more visit - https://docs.djangoproject.com/en/3.0/topics/db/managers/