No need to use get_context_data, use {{ view.some_method }}¶

There’s a super nice super elegant productivity trick for Django class based views. Something that is not very well know, as I discovered at last week’s djangocon. So… time to share it!

The problem? Getting information into your template’s context. What most people do is to overwrite get_context_data() , just like the example from the django 1.5 docs

def get_context_data ( self , ** kwargs ): # Call the base implementation first to get a context context = super ( PublisherDetailView , self ) . get_context_data ( ** kwargs ) # Add in a QuerySet of all the books context [ 'book_list' ] = Book . objects . all () return context

In the template you’d use it like this:

{ % for book in book_list % } ... { % endfor % }

The solution? A new feature in Django 1.5 : Django’s generic class based views now automatically include a view variable in the context. This variable points at your view object. So… you basically never need to modify get_context_data() anymore! Example:

from django.views.generic import TemplateView class SomethingView ( TemplateView ): template_name = "something.html" title = "My beautiful list of books" def books ( self ): return Book . objects . all () # Note: no get_context_data() here!

The template then uses the automatic view variable to grab the list of books and the title:

< h1 > {{ view . title }} </ h1 > < ul > { % for book in view . books % } < li > {{ book }} </ li > { % enfor % } < ul >

Isn’t that wonderful? It fits Django’s philosophy perfectly: the templates should be dumb, the processing should happen inside the view. Now it is dead easy to “just add a method” to calculate something, the method will automatically be available in the template as view.your_quick_helper_method .

No more tedious duplication like this:

from django.views.generic import TemplateView class SomethingView ( TemplateView ): def books ( self ): return Book . objects . all () def get_context_data ( self , ** kwargs ): context = super ( SomethingView , self ) . get_context_data ( ** kwargs ) context [ 'books' ] = self . books () # ^^^ bad duplication. return context

I mean, context['books'] = self.books() , that’s just plain unnecessary duplication. But… no need to do it anymore! Just call the method or grab the attribute directly.

Some notes: