Login

Using class methods as views

Author:
panyam
Posted:
June 22, 2009
Language:
Python
Version:
1.0
Score:
0 (after 0 ratings)

This set of handlers allow one to isolate requests based on the method posted. Normally, in a view, we would do checks for request.method value and update the resource accordingly. This makes the view code pretty messy.

So one way to avoid these check each time is to have a handler method (resource_handler above), that checks for the method parameter and dispatches to the handler withe the prefix <method>handler<suffix>.

This also has the advantage of grouping related actions in a particular class. At the same time a new instance of the request handler is not created on each request (as with the google appengine handler?). Yet another advantage is by making the handler methods as class methods, the handler classes can be inherited to add further functionality to a resource "group.

The disadvantage however is the inability to restrict access to a handler method to only particular methods. Eg above the "r'obja/(?P<id>[^/]+)/delete/" would map to the delete_handler_objects if themethod was "delete" and post_handler_objects if the method was "post". However this can be worked with a different suffix passed to the handler_params method. Infact setting the suffix to "objects_delete" would result in a "delete_handler_objects_delete" handler on delete method and a Http404 on all others.

Another inconvinience is the inability to detect a view handler by simply inspecting the url patterns. However, this information is carried within the handler_suffix and handler_class parameters which may infact provide greater insight into the semantics around the view handlers.

Needless to say, this easily extends rest based accesses.

Would greatly appreciate feedback and improvements.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from django.conf.urls.defaults import patterns, url
from django.http import HttpResponse

def resource_handler(request, handler_class, handler_suffix, method_param = "__method__", *args, **kwargs):
    method      = request.GET[method_param] if method_param in request.GET else request.method
    method      = method.lower()
    methodname  = method + "_handler_" + handler_suffix
    themethod   = getattr(handler_class, methodname, None)
    if themethod:
        return themethod(request, *args, **kwargs)
    else:
        raise Http404

def handler_params(cls, suffix):
    return {'handler_class': cls, 'handler_suffix': suffix}

class HandlerA(object):
    @classmethod
    def get_handler_objects(cls, request, id = None):
        if id:
            return HttpResponse("You have requested object of id: %s" % id)
        else:
            return HttpResponse("You have requesting listing og objecta")

    @classmethod
    def put_handler_objects(cls, request):
        return HttpResponse("You are creating a new object")

    @classmethod
    def post_handler_objects(cls, request, id):
        return HttpResponse("You are updating object of id: %s" % id)

    @classmethod
    def delete_handler_objects(cls, request, id):
        return HttpResponse("You are deleting object of id: %s" % id)

urlpatterns = patterns('',
    # front page
    url(r'obja/$', resource_handler, handler_params(HandlerA, "objects"), name="list_of_objecta"),
    url(r'obja/create/$', resource_handler, handler_params(HandlerA, "objects"), name="objecta_create"),
    url(r'obja/(?P<id>[^\/]+)/$', resource_handler, handler_params(HandlerA, "objects"), name="objecta_details"),
    url(r'obja/(?P<id>[^\/]+)/delete/$', resource_handler, handler_params(HandlerA, "objects"), name="objecta_delete"),
    url(r'obja/(?P<id>[^\/]+)/update/$', resource_handler, handler_params(HandlerA, "objects"), name="objecta_update"),
)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.