在url.py里,我们可以利用include()包含其他的url.py进来,但这样默认不支持使用login_required再次包装,如下所示的代码:
... (r'^blog/', login_required(include('blog.urls'))), )
会抛出异常。以下是一种解决方案(参考自StackOverflow):
''' 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
使用示例如下:
# ... ) urlpatterns += required( login_required, patterns('', (r'^blog/', include('blog.urls')) ) )