So, I came up with the following code that does just that.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Author: Stephen J. Zabel | |
License: BSD | |
This module exposed a helper function for | |
wrapping views at the urls.py/resolver level | |
My personal little itch as an example... | |
urlpatterns += required( | |
login_required, | |
patterns('', | |
(r'^api/', | |
include(api.urls)), | |
) | |
) | |
''' | |
def required(wrapping_functions,patterns_rslt): | |
''' | |
Used to require 1..n decorators in any view returned by a url tree | |
Usage: | |
urlpatterns = required(func,patterns(...)) | |
urlpatterns = required((func,func,func),patterns(...)) | |
Note: | |
Use functools.partial to pass keyword params to the required | |
decorators. If you need to pass args you will have to write a | |
wrapper function. | |
Example: | |
from functools import partial | |
urlpatterns = required( | |
partial(login_required,login_url='/accounts/login/'), | |
patterns(...) | |
) | |
''' | |
if not hasattr(wrapping_functions,'__iter__'): | |
wrapping_functions = (wrapping_functions,) | |
return [ | |
_wrap_instance__resolve(wrapping_functions,instance) | |
for instance in patterns_rslt | |
] | |
def _wrap_instance__resolve(wrapping_functions,instance): | |
if not hasattr(instance,'resolve'): return instance | |
resolve = getattr(instance,'resolve') | |
def _wrap_func_in_returned_resolver_match(*args,**kwargs): | |
rslt = resolve(*args,**kwargs) | |
if not hasattr(rslt,'func'):return rslt | |
f = getattr(rslt,'func') | |
for _f in reversed(wrapping_functions): | |
# @decorate the function from inner to outter | |
f = _f(f) | |
setattr(rslt,'func',f) | |
return rslt | |
setattr(instance,'resolve',_wrap_func_in_returned_resolver_match) | |
return instance |