参考URL:
https://blog.csdn.net/hanshengzhao/article/details/79540306?utm_source=blogxgwz0
1,首先定义一个内部有装饰器的函数,解析出每一个url中的path,并将login_required加在其前面。
def required(wrapping_functions, patterns_rslt): 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
2,在url.py中,将需要登陆的url放在urlpatterns_base列表中,之后,统一调用required函数进行登陆登陆。而不需要登陆的函数,就可以放在最后的urlpatterns延长列表之中。用户登陆的url千万不要放在base里。
""" 在urlpatterns_base统一定义需要用户登陆的url,且放置于required前面 不需要登陆的url,统一放在urlpatterns,位于required后面。 accounts用户登陆模块本身不需要登陆,不然会陷入循环要求登陆。 """ urlpatterns_base = [ path('', IndexView.as_view(), name='index'), path('admin/', admin.site.urls), ] urlpatterns_base += [ path('public/', include('public.urls')), ] urlpatterns_base += [ path('order/', include('order.urls')), # 取决于 order.urls里有没有app_name变量,以及实例命名和应用命名空间,写法多变 # 不管如何改变写法,app_namespace是必须的,而namespace是可选的 # path('order/', include(('order.urls', 'order'))), # 只定义app_name,两个括号不可少 # path('order/', include('order.urls')), # 这种情况下,下一层已定义好app_name # path('order/', include('order.urls'), namespace='order'), # 这种情况下,下一层已定义好app_name # path('order/', include(('order.urls', 'order'), namespace='order')), # 全写在第一层 ] # 为哪些url加上登陆要求 urlpatterns = required( login_required, urlpatterns_base ) urlpatterns += [ path('accounts/', include('accounts.urls')), ]