Decorating urlpatterns

 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
from django.core.urlresolvers import RegexURLPattern
from django.conf.urls.defaults import patterns

class DecoratedURLPattern(RegexURLPattern):
    def resolve(self, *args, **kwargs):
        result = RegexURLPattern.resolve(self, *args, **kwargs)
        if result:
            result = list(result)
            result[0] = self._decorate_with(result[0])
        return result

def decorated_patterns(prefix, func, *args):
    result = patterns(prefix, *args)
    if func:
        for p in result:
            if isinstance(p, RegexURLPattern):
                p.__class__ = DecoratedURLPattern
                p._decorate_with = func
    return result

def control_access(view_func):
    def _checklogin(request, *args, **kwargs):
        raise Http404()
    return _checklogin

urlpatterns = patterns('views',
    # unprotected views
    (r'^public/contact/$',      'contact'),
    (r'^public/imprint/$',        'imprint'),
) + decorated_patterns('views', control_access,
    (r'^admin/add/$',      'add'),
    (r'^admin/edit/$',      'edit'),
)

Comments

david_bgk (on January 2, 2008):

Why don't you use directly decorators in urls?

from foo.views import contact, imprint, add, edit

urlpatterns = patterns('',
    # unprotected views
    (r'^public/contact/$', contact),
    (r'^public/imprint/$', imprint),
    # protected views
    (r'^admin/add/$',  login_required(add)),
    (r'^admin/edit/$', login_required(edit)),
)

#

miracle2k (on January 3, 2008):

@david_bgk: It would break reverse().

Sure, I could name the patterns, and I have considered doing that from time to time, but so far I am not yet sure if I want to.

#

(Forgotten your password?)

You may use Markdown syntax here, but raw HTML will be removed.