烧瓶从关闭重定向

时间:2014-08-06 16:25:35

标签: redirect python-3.x flask closures

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化。

1 个答案:

答案 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,而另一个装饰路径功能也保持其名称