参考自
https://codeday.me/bug/20171128/102555.html
在写django 项目的时候,我的习惯是最后写权限控制,最简单的就是要写login_required了 。
正常情况下是在各个views 函数上面,一个个的加上装饰器。
@login_required
def index(request):
pass
再认真一点就是在url那里加上login_required。
urlpatterns = [
path('user/', login_required(user_manage), name="account_users_index"),
path('user/', login_required()(UserList.as_view()), name='account_users_list'),
]
但是如果路由再多一点,添加的工作量还是很大。如果要修改,就更麻烦了。
解决方案来了。就是在需要的地方只加一次。所有的都加。
#!/bin/env python
# -*- coding:utf-8 -*-
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
具体用法
urlpatterns_base = [
path('', index_view),
]
urlpatterns = required(
login_required,
urlpatterns_base
)
urlpatterns += [
path('login', include(zjxl_sso.get_login_urls())),
]