Support Our Site

To ensure we can continue delivering content and maintaining a free platform for all users, we kindly request that you disable your adblocker. Your contribution greatly supports our site's growth and development.

Adding Custom Model Managers In Django

2 min read

Table of Contents

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/


DJANGO

Latest Articles

Latest from djangocentral

How to Use Subquery() in Django With Practical Examples

In the realm of web development, Django stands as a powerful and versatile framework for building robust applications. One of the key aspects of developing efficient and optimized web applications is handling database queries effectively. In this article…
Read more →

4 min read

DRF Serializer: Handling OrderedDict and Converting It to a Dictionary or JSON

In Django Rest Framework (DRF) tests, when you access serializer.data, you might encounter an OrderedDict instead of a regular dictionary. This behavior is intentional and reflects the design of DRF's serialization process.Understanding the Problem The u…
Read more →

3 min read

Django Rest Framework CheetSheet: Mastering API Development

Django Rest Framework (DRF) is a powerful toolkit that makes building robust and scalable web APIs with Django a breeze. Whether you're a seasoned Django developer or a newcomer, having a comprehensive cheat sheet at your disposal can be a game-changer. …
Read more →

5 min read

How to Perform NOT Queries in Django ORM

In Django, performing NOT queries allows you to exclude certain records from the query results based on specific conditions. The NOT operator, represented by the tilde (~) when used in conjunction with the Django ORM's Q object, helps you construct compl…
Read more →

3 min read