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. I finally spent some time looking through the Django source, and I came up with the following:
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'), )
In this example, the latter two views will always raise a 404.
So far it seems to work quite nicely.
Nice approach. Did you happen to see my Tip of the Week on using the auth decorators for generic views? You can apply the same thing to any view really.
http://blog.michaeltrier.com/2007/12/17/this-week-in-django-2-2007-12-16
Keep up the good work.
LikeLike
I did actually. It’s a good idea, and for some reason I hadn’t even thought about approaching it like that. Although in my case, it would break the ability to use reverse() without explicitly naming the patterns, which is something I am relying on for now.
Of course if you’re using generic views, then that won’t be an issue.
LikeLike
Would be nice if this were extended to allow not only for RegexURLPatterns but also RegexURLResolvers e.g. include(‘app.urls’). Just a thought. Trying to extend it myself.
I don’t quite have it. Maybe you can provide a tip?
http://dpaste.com/56910/
LikeLike
http://dpaste.com/56911/ <– woops. Forgot.
LikeLike
I think you’re doing it right. The only mistake I can see right now is that you’re checking twice for RegexURLPattern:
“if isinstance(p, RegexURLPattern)“ instead of “if isinstance(p, RegexURLResolver)“
LikeLike