Login

RestfulView

Author:
whiteinge
Posted:
October 6, 2007
Language:
Python
Version:
.96
Score:
8 (after 8 ratings)

In the same vein as snippet 436, this allows you to differentiate view logic by HTTP method such as GET, POST, PUT, DELETE.

This is also very useful combined with the HttpMethodsMiddleware snippet.

I am not the author, but I have found it to be very helpful.

 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""
==========================
James Crasta's RestfulView
==========================

`As posted on Google Groups`__:

.. __: http://groups.google.com/group/django-developers/msg/5f066b7ce2197e82

-----
Usage
-----

Define a class which extends RestfulView in one of your views::

    class BlogComments(RestfulView):
        def _find_post(self, request, year, month, day, slug):
            " Helper function used in all the comment views "
            try:
                return Post.objects.find_post(year, month, day, slug)
            except Post.DoesNotExist:
                raise Http404()

        def handle_GET(self, request, year, month, day, slug):
            post = self._find_post(year, month, day, slug)
            posts = post.comment_set.filter(previewed=True)
            return render_to_response('blog/comments.html', {'posts': posts}

        def handle_POST(self, request, year, month, day, slug):
            post = self._find_post(year, month, day, slug):
            # do AddManipulator stuff here
            return render_to_response(..... )

Now, either instantiate the class in the view::

    comments = BlogComments() # this line goes after the class definition in your view

...then call that instance in your urlconf::

    urlpatterns = patterns('',
        (r'^archive/(?P<year>\d+)/(?P<month>\d+)/(?P<day>\d+)/(?P<slug>[\w-]+)/comments/',
        'myapp.blog.views.comments')

Or call it from your urlconf directly::

    from myapp.views.comments import BlogComments
    urlpatterns = patterns('',
        (r'^archive/(?P<year>\d+)/(?P<month>\d+)/(?P<day>\d+)/(?P<slug>[\w-]+)/comments/',
        BlogComments()) 

-----------
Usage Hints
-----------

You can use Django decorators if you forgo the class method
approach and use static functions. Obviously, you cannot reference
``self`` if you do this.

Here's a quick hint on possible usage with the above static
function and newforms::

    class TheClassName(RestfulView):
        @staticmethod
        def handle_GET(request, form=YourFormName()):
            # ...

        @staticmethod
        @login_required
        def handle_POST(request):
            form = YourFormName(request.POST)
            if form.is_valid():
                # ...
            else:
                return TheClassName.handle_GET(request, form=form)
"""

from django.http import HttpResponseNotAllowed

class RestfulView(object):
    def __call__(self, request, *args, **kw):
        # try and find a handler for the given HTTP method
        method = request.META['REQUEST_METHOD'].upper()
        handler = getattr(self, 'handle_%s' % method, None)

        if handler is None:
            # compile a list of all our methods and return an HTTP 405
            methods = []
            for x in dir(self):
                if x.startswith('handle_'):
                    methods.append(x[7:])
            return HttpResponseNotAllowed(methods)

        return handler(request, *args, **kw)

More like this

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

Comments

Please login first before commenting.