Django class based views: initial comments

Tags: django, plone

Note beforehand: I’m real happy that django has class based views now!

I’m an old zope/plone guy. And that’s object oriented all the way. So Django’s views always seemed a bit strange, being just a function you call. A simple function is fine, but you often want/need helper functions. So your soon starts to look like:

def homepage(...):

def overview(...):

def _helper_function1(...):

def _helper_function2(...):

def map(..):

def _helper_function3(...):

def _helper_function4(...):

Hurray, Django has class based views now!

So I greeted Django 1.3’s new class based views with enthousiasm! Visually, the same would now be something like:

class Homepage(TemplateView):

class Overview(TemplateView):

class Map(TemplateView):

Helper functions would now be methods inside the classes. And the possibility of class inheritance makes it easy to customize views. It would limit the amount of helper functions you’d need to import from other applications: you’d get them for free from your baseclass.

History lesson

I looked at django’s source code. Hello? 2004’s zope code wants is mixins back! Remember the “who cares about zope” keynote from Martijn Faassen at this year’s He said that zope is sometimes a couple of years ahead of django regarding choices that it makes.

Looking at django’s class based views means seeing lots of multiple inheritance with lots of mixin classes. TemplateResponseMixin, YearMixin, MultipleObjectTemplateResponseMixin, SingleObjectMixin. class BaseDateDetailView(YearMixin, MonthMixin, DayMixin, DateMixin, BaseDetailView)

Yep, looks much the same as the old zope2 code I used to be debugging :-) Multiple inheritance is fine and works well. Mixins are fine and work well. Unless it gets more elaborate and complex and you have to dig into at least five classes till you figure out which class does what. It is manageable at the moment, but will it still be so at django 1.5 or django 1.6?

When it gets too elaborate and your django views are a tangled mess of inheritance hiearchies, django can start doing what zope did after a few years of mixin classes: switch over to a component architecture (adapters+interfaces and so). Simpler and more robust. But with an extra layer of indirection and configuration, so it is still sometimes hard to figure out which component does what.

Anyway, I’ve now formally warned the django project that django 1.7 will probably contain a component architecture as that is what zope did some years ago :-)

Generic PR problem

Django’s great class based views have a generic PR problem: if you google for class based views, you find django’s documentation on class based generic views. When Martijn Faassen researched Django’s current state of the art for his keynote by reading the website, he found django’s class based views alright. But in his talk, he called them generic views all the time. A logical mistake!

When I saw that “generic view” term, my thoughts were as follows:

  • Generic views are those helper functions for a quick showing of a queryset that I hardly use as I write my own views, mostly.

  • Class based views are generic views.

  • So class based views don’t seem intended for your regular custom views.

Now, class based views are mighty fine for making generic views with. But doesn’t Django chase away people who want a regular custom view? Away from class based views? Just with the wording on the website?

There’s so much in place that’s not what you’d normally call a generic view in those class based views. So I think ‘generic’ takes up too much of the PR and that’s bad.

So what I’m going to do: explain how to make a regular class based view with Django! That’ll be a next article. logo

About me

My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):