Login

RFC: Shim to allow view classes rather than functions

Author:
peterbraden
Posted:
March 7, 2009
Language:
Python
Version:
1.0
Score:
0 (after 0 ratings)

This snippet is working code, however it is not intended for proper use, rather to garner comment on an alternative style of view - using a class for views, rather than a function.

While working with views, I've often felt that the traditional django code layout splits concerns in an unnatural fashion. The parameters for a view must be maintained in both the urls file as well as the view for example, and there is no neat way of grouping multiple accessor for a REST resource.

This 'shim' code aims to propose an alternative architecture, that is interchangeable with the existing system.

Rather than include a tuple of urls, instead a list of classes is provided. Each class models a resource, or page.

Page objects have a url property and name property, so it is therefor trivial to reconstruct the url tuple from the class, but allow more simplicity and structure in relating the methods of the resource.

You may notice that this structure closely follows the architecture of the web.py framework - this syntax did indeed play a part in the concept for such a structure.

While this paradigm may not be suitable in all situations, I believe it promotes a simpler, more encapsulated views architecture.

Any comments and feedback are welcomed.

Example usage (untested, sorry):

class Homepage(Page): def get(request): return HttpResponse("Hello World")

urlpatterns = patterns('', Homepage, url('^existing$', existing.view.function, name = "foo"), )

 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
from django.conf.urls.defaults import patterns as django_patterns
from django.conf.urls.defaults import url

def patterns(*urls):
	pages = []
	
	for cls in urls:
		if isinstance(cls, type):
			inst = cls()
			pages.append(url(inst.url, inst.resource, name = inst.name))
		else:
			#oldstyle resources
			pages.append(cls)
	return django_patterns(*pages)

	
class Page(object):
	
	url = r"^$"
	
	def resource(self, request, *args, **kwargs):
		if request.method == "GET":
			return self.get(request, *args, **kwargs)
		
		if request.method == "POST":
			return self.post(request, *args, **kwargs)
	
	@property
	def	name(self):
		return "%s-%s" % (self.__class__.__name__, "page")	

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

romain-hardouin (on March 12, 2009):

Do you want to make a view in style of RoR?

#

akaihola (on March 27, 2009):

I've experimented with class-based views in one of my projects. The nasty part is when you want to start using third-party or Django's stock decorators on your views while still being able to access individual methods and attributes in your unit tests.

#

Please login first before commenting.