Flask 视图中装饰器的顺序是否重要?
Does the order of decorators matter on a Flask view?
我正在使用 login_required
装饰器和另一个对输出数据进行分页的装饰器。谁先来很重要?
根据PEP 318,函数装饰器的语法是:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
这相当于:
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
并且 dec1 在 dec2 之前调用。
您可以像这样定义这些函数来检查:
def dec1(func):
print 'dec1'
def dec2(func):
print 'dec2'
@dec2
@dec1
def func():
pass
dec1
dec2
实际上它不会出现任何错误,但是如果您首先使用 login_reqired
并且用户未登录,应用程序将处理数据并在 login_required
函数生成一个 abort
Flask 中 login_required 装饰器的最佳实现是:
@paginate
@login_required
def view_function():
pass
虽然在这种情况下可能不会有任何问题,无论顺序如何,您可能希望 login_required
先执行,这样您就不会进行查询和分页结果,这些结果只会被抛出离开。
装饰器将原始函数从下到上包装起来,所以当函数被调用时,每个装饰器添加的包装器从上到下执行。 @login_required
应该在假设用户已登录的任何其他装饰器下方,以便在其他装饰器之前评估其条件。
@app.route()
必须始终是最顶层、最外层的装饰器。否则路由将被注册为一个不代表所有装饰器的函数。
更广泛的答案是,这取决于每个装饰者在做什么。您需要考虑您的程序流程,以及让一个程序先于另一个程序是否合乎逻辑。
根据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
Flask 文档指定如果函数是视图并且具有 route
装饰器,则顺序很重要。来自 the docs:
When applying further decorators, always remember that the
route() decorator is the outermost.
我正在使用 login_required
装饰器和另一个对输出数据进行分页的装饰器。谁先来很重要?
根据PEP 318,函数装饰器的语法是:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
这相当于:
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
并且 dec1 在 dec2 之前调用。
您可以像这样定义这些函数来检查:
def dec1(func):
print 'dec1'
def dec2(func):
print 'dec2'
@dec2
@dec1
def func():
pass
dec1
dec2
实际上它不会出现任何错误,但是如果您首先使用 login_reqired
并且用户未登录,应用程序将处理数据并在 login_required
函数生成一个 abort
Flask 中 login_required 装饰器的最佳实现是:
@paginate
@login_required
def view_function():
pass
虽然在这种情况下可能不会有任何问题,无论顺序如何,您可能希望 login_required
先执行,这样您就不会进行查询和分页结果,这些结果只会被抛出离开。
装饰器将原始函数从下到上包装起来,所以当函数被调用时,每个装饰器添加的包装器从上到下执行。 @login_required
应该在假设用户已登录的任何其他装饰器下方,以便在其他装饰器之前评估其条件。
@app.route()
必须始终是最顶层、最外层的装饰器。否则路由将被注册为一个不代表所有装饰器的函数。
更广泛的答案是,这取决于每个装饰者在做什么。您需要考虑您的程序流程,以及让一个程序先于另一个程序是否合乎逻辑。
根据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
Flask 文档指定如果函数是视图并且具有 route
装饰器,则顺序很重要。来自 the docs:
When applying further decorators, always remember that the route() decorator is the outermost.