zvoase
unread,Aug 25, 2008, 9:07:14 PM8/25/08Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Django users
Hey Django users, just a quick suggestion which might help a few
people.
I have come up with a way of writing a Django view as a class. I've
done this as part of an effort to write easier-to-understand RESTful
apps, as this allows the grouping of similar views as different types
of operation on a resource. Essentially, the solution goes something
like this:
* Views have to be callables which return HttpResponse objects.
* The problem with views as classes is that calling a view class
returns an instance of the view class, not HttpResponse.
* Solution: have the VC (view class) a subclass of HttpResponse.
This way, 'calling' the class will return a HttpResponse instance.
I've written a general class, Resource, which performs a dispatch on
the request method, so that a resource can be retrieved, created/
updated and deleted by writing 'get', 'put' and 'delete' methods on a
subclass of Resource.
A sample resource may look like this:
# CODE START #
class Book(Resource):
def get(self, request, book_name):
book = myapp.models.Book.objects.get(name=book_name)
return render_to_response('book_template.html', {'book':
book})
def put(self, request, book_name):
new_book, created = get_or_create(myapp.models.Book,
name=book_name)
new_book.data = request.raw_post_data
if created:
return HttpResponse(status=201)
return HttpResponse(status=200)
def delete(self, request, book_name):
book = myapp.models.Book.objects.get(name=book_name)
book.delete()
return HttpResponse()
# CODE END #
You can see how these methods correspond to GET, PUT and DELETE
request methods, and the dispatch is performed in the __init__ method
defined in the Resource class. HttpResponse instances can be returned
from these methods, and their data will be merged with 'self' by
__init__.
Okay, so here's the code I've written:
# CODE START #
class Resource(HttpResponse):
def __init__(self, request, *args, **kwargs):
HttpResponse.__init__(self)
if hasattr(self, request.method.lower()):
value = getattr(self, request.method.lower())(request, *args,
**kwargs)
if isinstance(value, HttpResponse):
self.update(value)
elif hasattr(self, 'run'):
value = self.run(request, *args, **kwargs)
if isinstance(value, HttpResponse):
self.update(value)
def update(self, response):
self._charset = response._charset
self._is_string = response._is_string
self._container = response._container
self._headers.update(response._headers)
self.cookies.update(response.cookies)
self.status_code = response.status_code
def render_to_response(self, *args, **kwargs):
self.update(render_to_response(*args, **kwargs))
# CODE END #
I hope people find this useful.
Regards,
Zack