Login

Rails-like MVC Controllers for Django

Author:
sciyoshi
Posted:
November 18, 2008
Language:
Python
Version:
1.0
Tags:
rails controller mvc
Score:
1 (after 1 ratings)

See the blog entry

Allows using controllers for views.

This allows for nice subclassing to override behavior of views. Controller.urls (see below) works fine for subclasses as well.

Similar to snippet #1165 except that it won't break reverse URL resolving and regex validation in URLs.

In views.py:

import mvc

class MyController(mvc.Controller):
   @mvc.view('myview/$', 'myview')
   def my_view(self):
       # do something with self.request
       return HttpResponse('something')

   class Meta(mvc.Controller.Meta):
       url_prefix = 'mycontroller-'

In urls.py:

from . import views

urlpatterns = patterns('',
    # ... other urls here ...
    *views.MyController.urls(r'prefix/')
)

Then the view MyController.my_view will be accessible from 'prefix/myview/' and have the name 'mycontroller-myview', i.e. reverse('mycontroller-myview') will work as expected.

 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
"""
Helpers for coding in a more MVC-fashion using Controller classes as opposed
to views.
"""

from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required

def view(path=None, name=None):
    def decorator(func):
        func.view = True
        func.name = name if name is not None else func.__name__
        func.path = path if path is not None else '^%s/$' % func.name
        return func
    return decorator

class ControllerMetaclass(type):
    @property
    def _meta(self):
        return self.Meta

    def urls(self, path_prefix=''):
        return [
            (path_prefix + view.path, self.get_handler(view), {}, self._meta.url_prefix + view.name)
        for view in (getattr(self, name) for name in dir(self)) if getattr(view, 'view', False)]

class Controller(object):
    __metaclass__ = ControllerMetaclass

    def __init__(self, request, *args, **kwargs):
        self.request = request

    @classmethod
    def get_view(cls, view, request, *args, **kwargs):
        return view(cls(request), *args, **kwargs)

    @classmethod
    def get_handler(cls, view):
        def inner(request, *args, **kwargs):
            return cls.get_view(view, request, *args, **kwargs)
        return reduce(lambda func, dec: dec(func), cls._meta.decorators, inner)

    class Meta(object):
        url_prefix = ''
        decorators = []

More like this

  1. ExtendibleModelAdminMixin by dokterbob 5 years, 5 months ago
  2. Decorator to modify reverse() to render SSL urls by AndrewIngram 6 years ago
  3. Revisiting Pygments and Markdown by djypsy 7 years, 9 months ago
  4. FieldsetForm by Ciantic 8 years ago
  5. Rails Style Controller by julan 6 years, 6 months ago

Comments

Please login first before commenting.