Django中一个视图的多个装饰器:执行顺序 [英] Multiple decorators for a view in Django: Execution order
问题描述
我正在尝试通过两个装饰器来装饰Django视图,一个用于检查登录,另一个用于检查is_active。
第一个是内置的 @login_required
,第二个是以下内容:
def active_required函数)
dec = user_passes_test(lambda u:u.is_active,'/ notallowed','')
return dec(function)
现在,Python中的装饰工具内部工作,但是以下内容不起作用:
code> @active_required
@login_required
def foo(request):
...
我想首先检查用户是否登录,如果没有登录,则重定向到登录页面,如果他或她登录,我想检查他或她是否活跃,如果没有,请执行重定向到'/ notallowed'
。
如果login_required失败,用户不会重定向到登录页面,但 @active_required
被执行,并且由于在这种情况下用户为空,所以@active_required装饰器失败,用户被重定向到 / notallowed
。
更改订单似乎工作,
@login_required
@active_required
def foo请求):
...
但我怀疑这种方法也有问题
组合两个装饰器的正确方式是什么,为什么执行顺序与简单的Python装饰器不同?
现在,Python中的装饰器工作在
嗯,我想这取决于你的内在定义。在你的情况下,你想要 login_required
先执行,所以它应该是最外层(顶部)装饰器
编辑
也许这些混淆是如何(这些特殊的)装饰器工作
login_required(original_view)
返回一个新视图,首先检查您是否登录,然后调用original_view
所以
login_required(
active_required(
my_view
)
)
首先检查您是否登录,然后
首先(第二)检查你是否活跃,然后
运行my_vew
I am trying to decorate a Django view by two decorators, one for checking login, and one for checking is_active.
The first one is the built-in @login_required
, and the second one is the following:
def active_required(function):
dec = user_passes_test(lambda u: u.is_active, '/notallowed', '')
return dec(function)
Now, the decorators in Python work inside out, however the following does not work:
@active_required
@login_required
def foo(request):
...
I want to first check if the user is logged in, and redirect to login page if not, and if he or she is logged in, I want to check whether he or she is active, and if not, perform redirect to '/notallowed'
.
What happens is that if the login_required fails, the user is not redirected to the login page, but @active_required
is executed, and since the user is null in that case, @active_required decorator fails and the user is redirected to /notallowed
.
Changing the order seems to work,
@login_required
@active_required
def foo(request):
...
but I suspect there is something wrong with this approach too.
What is the proper way to combine two decorators, and why does the execution order differ from simple Python decorators?
Now, the decorators in Python work inside out
Well i guess that depends on your definition of inside out. in your case you want login_required
to execute first, and so it should be the "outermost" (top) decorator
as you noted, your last example works, and is indeed the correct way to do this
edit
maybe the confusion is with how (these particular) decorators work
login_required(original_view)
returns a new view, which first checks if you are logged in, and then calls original_view
so
login_required(
active_required(
my_view
)
)
first checks if you are logged in, then
first(second) checks if you are active, then
runs my_vew
这篇关于Django中一个视图的多个装饰器:执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!