Django中一个视图的多个装饰器:执行顺序
我正在尝试由两个装饰器装饰Django视图,一个装饰器用于检查登录,另一个用于检查is_active。
第一个是内置的@login_required
,第二个如下:
def active_required(function):
dec = user_passes_test(lambda u: u.is_active, '/notallowed', '')
return dec(function)
现在,Python中的装饰器可以由内而外工作,但是以下操作不起作用:
@active_required
@login_required
def foo(request):
...
我想首先检查用户是否已登录,如果没有,请重定向到登录页面,如果他或她已登录,则要检查他或她是否处于活动状态,如果不是,则执行重定向到'/notallowed'
。
发生的情况是,如果login_required失败,则不会将用户重定向到登录页面,而是@active_required
会执行该用户,并且由于在这种情况下用户为null,@
active_required装饰器将失败,并将用户重定向到/notallowed
。
更改顺序似乎可行,
@login_required
@active_required
def foo(request):
...
但我怀疑这种方法也有问题。
组合两个装饰器的正确方法是什么,为什么执行顺序与简单的Python装饰器不同?
-
现在,Python中的装饰器由内而外地工作
好吧,我想这取决于您由内而外的定义。对于您的情况,您要
@login_required
首先执行,因此它应该是“最外面的”(顶部)装饰器。如您所述,您的最后一个示例有效,并且确实是实现此目的的正确方法。
编辑
困惑可能是这些特定装饰器的工作方式。
@login_required(@original_view)
返回一个新视图,该视图首先检查您是否已登录,然后调用original_view所以
@login_required( @active_required( @my_view ) ) first checks if you are logged in, then first(second) checks if you are active, then runs my_view