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
- Django Settings Assignment Expressions aka Walrus Operator example by webology 2 weeks, 6 days ago
- codigo alto nivel by MrRocklion 2 months, 2 weeks ago
- Load template from specific app by Krzysiek555 3 months, 1 week ago
- PostgreSQL JSON subqueries by dolamroth 3 months, 1 week ago
- "Magic Link" Management Command by webology 8 months, 2 weeks ago