About •  Books •  Apps •  Jobs •   Feeds •  Twitter
Login

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:

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