Archive for August, 2010

Decorating Django view classes

August 5, 2010 Leave a comment

Last time we introduced a way to use classes for Django views instead of functions. One side effect of this is that you need a separate base class for each type of renderable returned from the callable. Well, not if you use decorators.

from django.shortcuts import render_to_response

class RenderResponseDecorator(object):
    def __init__(self, callable):
        self.callable = callable

    def __call__(self, request, *args, **kwargs):
        template, handler = self.callable(request, *args, **kwargs)
        return render_to_response(template, handler)

class HandlerBase(object):
    Base class for event handler.  This is an abstract base class for a dispatcher.
    @param template: C{str} the template to be used for rendering
    def __init__(self, *args, **kwargs):
        self.response_dict = dict()

    def _lookup(self, request=None, *args, **kwargs):
        looks up the proper handler for the event response.
        @param request: The response from the server
        handler = getattr(self, "event_%s" %request.method.lower(), None)
        return handler(request, *args, **kwargs)

class Handler(HandlerBase):
    Handler for processing unauthenticated web pages
    def __init__(self, template, *args, **kwargs):
        self.template = template
        super(Handler, self).__init__()

    def __call__(self, request=None, *args, **kwargs):
        return self._lookup(request, template=self.template)

class HandlerTest(Handler):
    def __init__(self, template=None, *args, **kwargs):
        super(HandlerTest, self).__init__(template, *args, **kwargs)

    def event_get(self, request=None, template=None, *args, **kwargs):
        return template, {"response": "Hello, world!"}

So now, instead of having to build a separate base class for each type of response, we simply build one decorator for each response simplifying our inheritance tree.

Categories: Django, Python