Resource

 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
import string

from django.http import HttpResponse, HttpResponseNotAllowed


class Resource(HttpResponse):
    
    """Represents a single resource within a RESTful web service.
    
    The ``Resource`` class should be used to represent a single resource
    within a RESTful web service. It exists to be subclassed for each
    resource within the service, and these subclasses should define a method
    for each possible HTTP request method on the so"""
	
	def __init__(self, request, *args, **kwargs):
	    """Instantiate a ``Resource`` instance.
	    
	    This method overrides ``HttpResponse.__init__``, providing an
	    alternative way of serving views. It calls the overridden method
	    first, to handle the initialization, and then performs a dispatch
	    on the HTTP request method. The return values of these methods are
	    then merged back into the current ``HttpResponse`` instance.
	    
	    Because this is called like a view function, this method accepts
	    a request object and any other positional and/or keyword arguments,
	    These will be passed to the methods defined on a subclass, so those
	    methods should support any arguments given.
	    
	    If the given HTTP request method is not defined for a subclass, then
	    a 405 'Method Not Allowed' response is returned, along with a list
	    of allowed methods (obtained via introspection)."""
		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)
		else:
		    allowed_methods = []
		    for attr in dir(self):
		        if set(attr).issubset(set(string.lowercase)):
		            allowed_methods.append(attr.upper())
		    self._update(HttpResponseNotAllowed(sorted(allowed_methods)))
	
	def _update(self, response):
	    """Merge the info from another response with this instance.
	    
	    This method simply copies the attributes from the given response to
	    this instance, with the exceptions of the ``_headers`` and ``cookies``
	    dictionaries, whose ``update`` methods are called. This means that any
	    headers or cookies which are present in this response but not the
	    argument are preserved."""
		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

More like this

  1. Base class for RESTful Views by jpwatts 5 years, 4 months ago
  2. Ajax API class by kcarnold 5 years, 10 months ago
  3. EasyFeed class by limodou 7 years, 1 month ago
  4. RESTful class dispatch by Phoenix 4 years, 10 months ago
  5. URL models by diverman 4 years, 6 months ago

Comments

bryhoyt (on March 6, 2010):

Shouldn't you be checking that attr is in a list of allowed HTTP methods (GET/POST/PUT etc)? Otherwise the client-side could execute arbitrary methods of any subclass of Resource.

#

(Forgotten your password?)