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 | """
Example usage:
class ArticleView(RestView):
def GET(request, article_id):
return render_to_response("article.html", {
'article': get_object_or_404(Article, pk = article_id),
})
def POST(request, article_id):
# Example logic only; should be using django.forms instead
article = get_object_or_404(Article, pk = article_id)
article.headline = request.POST['new_headline']
article.body = request.POST['new_body']
article.save()
return HttpResponseRedirect(request.path)
Then in your urls.py:
from my_views import ArticleView
urlpatterns = patterns('',
...
(r'^article/(\d+)/$', ArticleView()),
...
)
"""
from django.http import HttpResponse
import re
nonalpha_re = re.compile('[^A-Z]')
class RestView(object):
"""
Subclass this and add GET / POST / etc methods.
"""
allowed_methods = ('GET', 'PUT', 'POST', 'DELETE', 'HEAD', 'OPTIONS')
def __call__(self, request, *args, **kwargs):
method = nonalpha_re.sub('', request.method.upper())
if not method in self.allowed_methods or not hasattr(self, method):
return self.method_not_allowed(method)
return getattr(self, method)(request, *args, **kwargs)
def method_not_allowed(self, method):
response = HttpResponse('Method not allowed: %s' % method)
response.status_code = 405
return response
|
Comments
This is all very well and good, but methods defined on the subclass also have to accept
selfas a positional argument, or be decorated bystaticmethod. Also, having an actualselfwhich is persistent across requests may provide risks to thread safety, etc.I've implemented something similar, only it uses some magic to alleviate two problems:
staticmethodorselfat any point in the method definitions.You can get to that here
#
Exactly the same as Snippet 437.
#
Hah! I was sure someone else had done this before (it's an obvious approach) but my Google-fu failed me.
#