Class based views
We discussed these at a recent Vancouver Django (May 2009) meetup and it was also a pattern I used on a recent project.
Traditionally in Django a URL points to a function. So something like this is probably what you familar with:
from django.conf.urls.defaults import patterns
urlpatterns = patterns('',
(r'^hello-function/$', 'recipe_9.views.hello_function')
)
And a view that looks like this:
from django.http import HttpResponse
def hello_function(request):
return HttpResponse("Hello world!")
As it turns out, Django only needs something that is callable, so this can be a class. Let's just show the difference. The URLs:
from django.conf.urls.defaults import patterns
from views import hello_class
urlpatterns = patterns('',
(r'^hello-class/$', hello_class()),
)
The class:
from django.http import HttpResponse
class hello_class:
def __call__(self, request):
return HttpResponse("Hello world!")
Oh and let's not forget some tests to prove this works:
from django.test import TestCase
from django.test.client import Client
class tests(TestCase):
def testFunction(self):
clt = Client()
res = clt.get("/hello-function/")
assert res.status_code == 200
assert res.content == 'Hello world!'
def testClass(self):
clt = Client()
res = clt.get("/hello-class/")
assert res.status_code == 200
assert res.content == 'Hello world!'
What's the advantage of this? Well since it's a class you get all the advantages of being a class, doing things on the __init__, subclassing, overriding the __call__ and so on. Let's take an example. An extension of the Kenyan project for me recently was a similar project in another country. Similar, but of course, not the same. There were differences in the text and how certain situation are handled. So I made all the views point to classes (at this point I will add I also altered our URLResolver)... anyway all the requests in these projects do that same thing:
- parse the user input into a form
- validate the user input
- process it
- return an response
This logic of processing the request in this order has been pushed into a class. All my views inherit from it. So now the code for country X only deals with the specific parts for that country. When I add country Z to the mix, I just need to change the specific parts for that country.
Whilst this may sound a bit specialised, many applications can use this. For example one of the first applications I have takes every request and then checks the account information on that request (it doesn't use session for other reasons). So the first line of every view is a call to go and get that information. Making a part of template request processor sort of works, but you have to do work to dig that back out.
In the end making it a class based view adds only about 3 lines of code but makes you app much more reusable and adaptable in the future.
References:
Comments
There are no comments.
Login to add comments

