Creating model managers
As we previously mentioned, objects is the default manager of every model that retrieves all objects in the database. However, we can also define custom managers for our models. We will create a custom manager to retrieve all posts with the published status.
There are two ways to add managers to your models: you can add extra manager methods or modify initial manager QuerySets. The first method provides you with a QuerySet API such as Post.objects.my_manager(), and the latter provides you with Post.my_manager.all(). The manager will allow us to retrieve posts using Post.published.all().
Edit the models.py file of your blog application to add the custom manager:
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager,
self).get_queryset()\
.filter(status='published')
class Post(models.Model):
# ...
objects = models.Manager() # The default manager.
published = PublishedManager() # Our custom manager.
The get_queryset() method of a manager returns the QuerySet that will be executed. We override this method to include our custom filter in the final QuerySet. We have defined our custom manager and added it to the Post model; we can now use it to perform queries. Let's test it.
Start the development server again with the following command:
python manage.py shell
Now, you can retrieve all published posts whose title starts with Who using the following command:
Post.published.filter(title__startswith='Who')