装饰器的顺序在Flask视图上是否重要?

时间:2015-01-28 23:01:14

标签: python flask python-decorators flask-login

我使用login_required装饰器和另一个分页输出数据的装饰器。重要的是哪一个先来?

4 个答案:

答案 0 :(得分:9)

虽然在这种情况下可能不存在任何问题,但无论顺序如何,您可能首先要执行login_required,这样您就不会进行查询和分页结果,这些结果将被丢弃。

装饰器将原始函数从底部包装到顶部,因此当调用该函数时,每个装饰器添加的包装器从上到下执行。所以login_required应该高于假设用户已登录的任何其他装饰器。


更广泛的答案是,它取决于每个装饰者正在做什么。你需要考虑你的程序流程,以及一个人在另一个程序之前是否具有逻辑意义。

答案 1 :(得分:2)

根据PEP 318,函数装饰器的语法是:

@dec2
@dec1
def func(arg1, arg2, ...):
    pass

这相当于:

def func(arg1, arg2, ...):
    pass
func = dec2(dec1(func))
在dec2之前调用

和dec1。

您可以定义这些功能,如下所示:

def dec1(func):
    print 'dec1'
def dec2(func):
    print 'dec2'

@dec2
@dec1
def func():
    pass
dec1
dec2

实际上它没有出现任何错误,但是如果您先使用login_reqired并且用户未登录应用程序将处理数据并在login_required函数生成中止后对其进行分页

烧瓶中login_required装饰器的最佳实现是:

@paginate
@login_required
def view_function():
    pass

答案 2 :(得分:2)

根据login_required的实现,

def login_required(func):
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if current_app.login_manager._login_disabled:
            return func(*args, **kwargs)
        elif not current_user.is_authenticated():
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view

你应该像下面这样做。

@login_required
@paginate
def view_function():
    pass

假设您有另一个装饰者is_admin来判断用户是否拥有管理员权限,您应该像下面这样做

@login_required
@is_admin
def view_function():
    pass

答案 3 :(得分:2)

Flask文档指定,如果函数是视图且具有route装饰器,则顺序很重要。来自the docs

  

在应用其他装饰器时,请始终记住   route()装饰器位于最外面。