Login

RestfulView

Author:
whiteinge
Posted:
October 6, 2007
Language:
Python
Version:
.96
Tags:
rest http urlconf
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. Sanitize HTML filter by henriklied 8 years, 1 month ago
  2. Currency Widget by Rupe 6 years ago
  3. improved getattr template filter by luckystarr 7 years, 8 months ago
  4. Currency Form Field by Rupe 6 years ago
  5. Currency DB Field by Rupe 6 years ago

Comments

Please login first before commenting.