One thing I wanted for a while was the ability to basically apply something like @login_required to a bunch of urlpatterns in one go, instead of having to decorate each and every view manually.
In this example, the latter two views will always raise a 404.
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'),
)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Why don't you use directly decorators in urls?
from foo.views import contact, imprint, add, edit
#
@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.
#
if you want to user included url files, like so
modify decorated_patterns to be:
def decorated_patterns(prefix, func, *args):
#
This snippet works great, and allows you to enforce some precondition for a large number of URLs in one go (when using the fix from comment 3.).
If you add
**kwargs
to decorated_patterns, it also works with named patterns.In my opinion, this is extremely useful, and the snippet is greatly underrated.
Thanks for sharing this!
#
This is broken in Django 1.3.
To fix it, replace the DecoratedURLPattern class with this:
#
Thanks aehlke! :)
#
Aaand to fix it with Django 1.6, replace _get_url_patterns() with url_patterns
:) Oh the joys of maintenance.
#
Please login first before commenting.