Login

RFC: Shim to allow view classes rather than functions

Author:
peterbraden
Posted:
March 7, 2009
Language:
Python
Version:
1.0
Tags:
views rfc
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. Django Class Views by rmt 5 years, 9 months ago
  2. Effective content caching for mass-load site using redirect feature by nnseva 3 years, 8 months ago
  3. Ajax API class by kcarnold 6 years, 9 months ago
  4. Row-Level, URL-based permissions for FlatPages by bradmontgomery 5 years, 9 months ago
  5. Allow separation of GET and POST implementations by agore 2 years, 9 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.