def check_login(func):
"""Check if user is logged in."""
def decorator(*args, **kwargs):
if not login_session_test():
print ("Not logged in - redirect to /login")
flash ("Well that was wrong. Chicken winner. No more dinner.")
return redirect(url_for('login'))
print ("Logged in, do what needs to be done.")
return func(*args, **kwargs)
return decorator
@check_login
@app.route("/sacred/secret/stuff", methods=['GET'])
def funfunfun():
return "Super fun"
它永远不会重定向到/login
,但会给页面带来一些垃圾。
交换@
/封闭订单会产生:
AssertionError: View function mapping is overwriting an existing endpoint function: decorator
我还没有完全python化。
答案 0 :(得分:1)
您的装饰器顺序不正确,并且您没有将函数名称复制到包装函数。
使用此订单:
@app.route("/sacred/secret/stuff", methods=['GET'])
@check_login
def funfunfun():
return "Super fun"
否则会为视图注册未修饰的功能。
使用@functools.wraps()
将各种元数据从原始包装函数复制到替换它的包装器中:
from functools import wraps
def check_login(func):
"""Check if user is logged in."""
@wraps(func)
def decorator(*args, **kwargs):
if not login_session_test():
print ("Not logged in - redirect to /login")
flash ("Well that was wrong. Chicken winner. No more dinner.")
return redirect(url_for('login'))
print ("Logged in, do what needs to be done.")
return func(*args, **kwargs)
return decorator
路由需要一个端点名称,如果您没有明确指定,则Flask使用该函数的名称(来自functionobj.__name__
)。但是你的装饰器包装器对象的名称为decorator
,所以如果你多次使用装饰器,那么Flask会抱怨它已经使用了那个端点名称。
@functools.wraps()
复制__name__
属性,所以现在你的装饰包装器也称为funfunfun
,而另一个装饰路径功能也保持其名称