Django Quick Tips #1: Managers
February 12, 2007
This post is the first in a series of "Quick Tips" for Django, short bits of information not meant to be exhaustive but introductory. Django is such a massive framework that it's easy to miss a great feature. It's also easy to miss the point of functionality when it isn't accompanied with a useful example.
This Quick Tip is a brief explanation of Managers. From the Django docs:
A Manager is the interface through which database query operations are provided to Django models.
Django automatically assigns the default manager with the name objects, giving us read/write access to our new model.
MyModel.objects.all() # Using the Manager's built-in all() method
Here's a real world example of why it might be prudent to create a custom manager. Let's say we have a simple blog model that allows us to publish/unpublish our posts.
from django.db import models
class Post(models.Model):
title = models.CharField(maxlength=100)
text = models.TextField()
published = models.BooleanField()
Now, when we want to show a published article we have to filter it by published.
Post.objects.filter(published=True)
Unfortunately, it can be easy to forget since you're going to be putting this in many places. Instead, we'll create a Manager to do the work for us. A Manager essentially helps us build a queryset, so creating a custom manager allows us to filter the queryset.
Here is our PublishedPostManager:
class PublishedPostManager(models.Manager):
def get_query_set(self):
return super(PublishedPostManager,
self).get_query_set().filter(published=True)
We put that above our Model and add it as published_objects.
from django.db import models
class Post(models.Model):
title = models.CharField(maxlength=100)
text = models.TextField()
published = models.BooleanField()
objects = models.Manager()
published_objects = PublishedPostManager()
Note: We must add the objects default Manager if we want it back, otherwise Django will use published_objects as the default instead. That would make all unpublished posts disappear, including the admin panel!
Now, we can pass the published_objects as our queryset:
Post.published_objects.all() # Only returns posts where published == True Post.objects.all() # Returns all posts
If we change the criteria of what it means to be published, for example "date must be today or older", then we only have to modify the queryset in the Model. This certainly reduces code and the possibility for error and oversight.
Hopefully this example will give you a glimpse of what Managers can do for you. The Django docs are a good place for more information.
Add your comment
No HTML; Only URLs and line breaks are converted.
Comments
Clean and nice. Shows what django can do rather well I think.
Posted by Tony
Thanks, this is quite clear and strait forward.
Posted by Noah
quick and informative, thx!
Posted by costi
Thanks, just what I needed
Posted by a