Django中一个视图的多个装饰器:执行顺序 [英] Multiple decorators for a view in Django: Execution order

查看:726
本文介绍了Django中一个视图的多个装饰器:执行顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过两个装饰器来装饰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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆