Login

Decorating URL includes

Author:
cotton
Posted:
August 25, 2011
Language:
Python
Version:
1.3
Score:
2 (after 2 ratings)

Apply a decorator to every urlpattern and URLconf module returned by Django's include() method . This allows you use a decorator on any number of views without having to decorate each one individually.

The use case here is wrapping all of the Django Admin with a superuser decorator. This is code that's better left alone where we can't actually go in and decorate the Admin views and urlpatterns manually. It's also almost guaranteed the Admin will include() other URL files. So the added bonus is all the INSTALLED_APPS that have their admin.py files registered by admin.autodiscover() will be decorated automatically as well.

This snippet is greatly inspired by @miracle2k's excellent #532. In the comments there @timbroder offers a modification to decorate includes but I think this is cleaner, simpler code and not subject to changes in the Django base code driving _get_url_patterns().

 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
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
from django.conf.urls.defaults import patterns, url, include
from django.contrib import admin
from myproject.myapp.decorators import superuser_required

class DecoratedURLPattern(RegexURLPattern):
    def resolve(self, *args, **kwargs):
        result = super(DecoratedURLPattern, self).resolve(*args, **kwargs)
        if result:
            result.func = self._decorate_with(result.func)
        return result

class DecoratedRegexURLResolver(RegexURLResolver):
    def resolve(self, *args, **kwargs):
        result = super(DecoratedRegexURLResolver, self).resolve(*args, **kwargs)
        if result:
            result.func = self._decorate_with(result.func)
        return result

def decorated_includes(func, includes, *args, **kwargs):
    urlconf_module, app_name, namespace = includes
    
    for item in urlconf_module:
        if isinstance(item, RegexURLPattern):
            item.__class__ = DecoratedURLPattern
            item._decorate_with = func
            
        elif isinstance(item, RegexURLResolver):
            item.__class__ = DecoratedRegexURLResolver
            item._decorate_with = func

    return urlconf_module, app_name, namespace

# urls.py - usage example with the admin site
adminurls = include(admin.site.urls)

urlpatterns = patterns('',
    # normal views
    (r'^assets/', include('myapp.assets.urls')),

    # all of these views are decoratored
    (r'^admin/', decorated_includes(superuser_required, include(admin.site.urls)) ),
)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 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

s29 (on October 26, 2011):

awesome, thanks!

#

Please login first before commenting.