Django — Model Manager

Whenever we use the Django ORM to query a model, we use the model manager to interact with the database. Model Managers are said to act on the full set of all instances of this model class( all the data in the table ) to restrict the ones you want to work with. Django provides a default model manager for each model class, but we can define it on our own. For e.g.:

from django.db import models
from django.utils import timezone

class PublishedManager(models.Manager):
  def published(self, **kwargs):
    return self.filter(pub_date__lte=timezone.now(), **kwargs)
  
class FlavorReview(models.Model):
  review = models.CharField(max_length=255)
  pub_date = models.DateTimeField()
  # add our custom model manager
  objects = PublishedManager()

Now, if we first want to display a count of all of the ice cream flavor reviews, and then a count of just the published ones, we can do the following:

from reviews.models import FlavorReview
FlavorReview.objects.count()
35
FlavorReview.objects.published().count()
31

This is good but still wouldn’t it make more sense if you just added a second model manager? That way you could have something like:

from reviews.models import FlavorReview
FlavorReview.objects.filter().count()
35
FlavorReview.published.filter().count()
31

On the surface, replacing the default model manager seems like an intelligent thing to do. Unfortunately, our experiences in real project development make us very careful when we use this method. Why?

First, when using model inheritance, children of abstract base classes receive their parent’s model manager, and children of concrete base classes do not.

Second, the first manager applied to a model class is the one that Django treats as the default. This breaks significantly with the normal Python pattern, causing what can appear to be unpredictable results from QuerySets.

Warning: Know the Model Manager Order of Operations

Always set objects = models.Manager() above any custom model manager
that has a new name. While this rule can be broken, it’s an advanced 
technique that we don’t recommend for most projects.

Happy Coding!!