Customization: Custom managers

  1. Customization
  2. Extra filters and tags

http://docs.djangoproject.com/en/dev/topics/db/managers/

Just about everything is an object in Django. The “objects” that you use for “Blog.objects.filter()”, “Blog.objects.all()”, and “Blog.objects.exclude()” is a “manager” object, and you can override it. For example, it might be nice to be able to post-date blog articles so that they become public at a specific time. If we do that, we need to pay attention to both “live=True” and “Date__lte=datetime.now()”. Currently, that means changing two functions, but you can imagine a more complex blog where the code asks for “all live posts” all over the place.

It would be nice to have a single place to ask for all live—or all public—posts. We can override the manager, and then tell Django to use our custom manager for all uses of Post.objects.

First, edit models.py to add the new manager.

class PostManager(models.Manager):

def public(self):

return self.all().filter(live=True, date__lte=datetime.now()).order_by('-date')

There are several __ modifiers you can use in filter and exclude; “lte” means “less than or equal to”. You’ll also need to import the “datetime” functionality so that it can use “datetime.now()” to get the current date and time:

from datetime import datetime

And then tell the Post object to use this new manager:

class Post(models.Model):

title = models.CharField(max_length=120)

changed = models.DateTimeField(auto_now=True)

objects = PostManager()

Then, in listPosts in views.py, change “posts = Post.objects.filter(live=True).order_by('-date')” to:

posts = Post.objects.public()

And in showPost, change “post = get_object_or_404(Post, slug=postSlug, live=True)” to:

post = get_object_or_404(Post.objects.public(), slug=postSlug)

The “or_404” functions accept both a model class and a queryset.

And finally, in topicalPosts, change “posts = Post.objects.filter(live=True, topics=topic).order_by('-date')” to:

posts = Post.objects.public().filter(topics=topic)

Yes, you can chain filter and exclude. If you have any custom manager methods, however, they must go first, and you can’t use more than one custom manager method in the chain.

If you now change the date and time on one of the posts to be a minute from now, it will temporarily disappear from the list, and then reappear when its time comes. And it will do this on every page that used to display it.

  1. Customization
  2. Extra filters and tags