【问题标题】:flask redirect from closure烧瓶从关闭重定向
【发布时间】:2014-08-06 16:25:34
【问题描述】:
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,但会给出一些垃圾页面。

交换@/closure 订单产生:

AssertionError: View function mapping is overwriting an existing endpoint function: decorator

我还没有完全 Python 化。

【问题讨论】:

    标签: redirect python-3.x flask closures


    【解决方案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,而另一个装饰路由函数也可以保留它的名字。

    【讨论】:

    • 如果我的装饰器和登录测试在另一个文件/模块中怎么办?我明白了werkzeug.routing.BuildError: Could not build url for endpoint 'login'. Did you mean 'static' instead?
    • @nmz787 只要该模块已导入,它就可以工作。您可以在命令行上运行flask routes 以获取完整列表(可以选择以各种方式对它们进行排序)。最后但同样重要的是:如果您正在使用蓝图,则需要在名称前加上蓝图名称和一个点(如果您在注册到同一蓝图的视图中,则只需一个点)。
    猜你喜欢
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2013-10-08
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    相关资源
    最近更新 更多