我正在try 由两个装饰者装饰Django视图,一个用于判断登录,另一个用于判断is_active.

第一个是内置的@login_required,第二个是:

def active_required(function):
    dec = user_passes_test(lambda u: u.is_active, '/notallowed', '')
    return dec(function)

现在,Python中的decorator 由内而外工作,但是以下内容不起作用:

@active_required
@login_required
def foo(request):
    ...

我想先判断用户是否登录,如果没有,重定向到登录页面,如果他/她登录,我想判断他/她是否处于活动状态,如果没有,执行重定向到'/notallowed'.

如果所需的登录失败,用户不会被重定向到登录页面,但会执行@active_required,因为在这种情况下用户为空,@active_required decorator失败,用户被重定向到/notallowed.

改变顺序似乎有效,

@login_required
@active_required
def foo(request):
    ...

但我怀疑这种方法也有问题.

组合两个decorator 的正确方式是什么,为什么执行顺序与简单的Pythondecorator 不同?

推荐答案

现在,Python中的装饰者从内到外工作

嗯,我想这取决于你对"由内而外"的定义.在您的例子中,您希望首先执行@login_required,因此它应该是"最外层"(顶部)的装饰符.

正如您所指出的,您的最后一个示例是有效的,而且确实是正确的方法.

edit

令人困惑的可能是这些特殊的装饰师是如何工作的.

@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

Django相关问答推荐

使用序列化器获取Django ORM auth_user. id数据

Django-无法显示基于字段值的元素

无法在 docker 启动Django项目

我的Django终结点不访问HAS_OBJECT_PERMISSION方法

将所有守护用户对象权限从一个Django用户重新分配给另一个Django用户

带有变量键的 Django 模板括号表示法不起作用

Django多对多关系报错:<title> object (None)>需要先设置id字段的值.

DJANGO 获得模型中发现的第一、第二和第三大价值

Django 相当于子查询

Django Inline Tabular admin:删除一个不工作的对象

django 的 Manager.create() 方法有什么作用?

如何在 Django 模板中的计数器上进行 for 循环中断?

在 Django Admin change_list 视图中更改 list_editable 字段时保存 Django 模型

Django 表单有 Select 但也有自由文本选项?

如何在 django tests.py 中创建管理员用户

__init__() 得到了一个意外的关键字参数user

Django 有 SmallIntegerField 的原因是什么?

Django将HttpResponseRedirect返回到带有参数的url

Django 应用程序运行良好,但收到 TEMPLATE_* 警告消息

Numpy 数组到 base64 并返回到 Numpy 数组 - Python