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

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to