如何在烧瓶中使用g.user全局

正如我理解Flask中的gvariables,它应该为我提供一个全局的地方来存储数据,例如login后保存当前用户。 它是否正确?

我希望我的导航在login网站时显示我的用户名。

我的意见包含

from Flask import g #among other things 

在login期间,我分配

 user = User.query.filter_by(username = form.username.data).first() if validate(user): session['logged_in'] = True g.user = user 

我似乎无法访问g.user。 相反,当我的base.html模板具有以下…

 <ul class="nav"> {% if session['logged_in'] %} <li class="inactive">logged in as {{ g.user.username }}</li> {% endif %} </ul> 

我得到的错误:

 jinja2.exceptions.UndefinedError UndefinedError: 'flask.ctx._RequestGlobals object' has no attribute 'user' 

login,否则工作正常。 我错过了什么?

g是本地线程,并且是每个请求(请参阅代理注释 )。 session 也是一个本地线程,但是在默认情况下是持久化到一个MAC签名的cookie并发送到客户端。

您遇到的问题是session在每个请求session被重build(因为它被发送到客户端,并且客户端把它发回给我们),而在g上设置的数据只在这个请求的有效期内可用。

最简单的事情(注意simple != secure – 如果你需要安全的话,看一下Flask-Login )就是简单地将用户的ID添加到会话中,并在每个请求上加载用户:

 @app.before_request def load_user(): if session["user_id"]: user = User.query.filter_by(username=session["user_id"]).first() else: user = {"name": "Guest"} # Make it better, use an anonymous User instead g.user = user 

g修正后,g对象现在绑定到应用程序上下文而不是请求上下文。

“从Flask 0.10开始,它存储在应用程序上下文中,不再在请求上下文中,这意味着如果只有应用程序上下文被绑定,并且还没有请求,它就变为可用。

我会试图摆脱全部在一起,把你的应用程序看作是一组执行任务的函数,每个函数都有input和输出,而不应该碰到全局variables。 只需获取用户并传递给用户,这会使您的代码更加可testing。 更好的是:摆脱瓶,烧瓶促进使用全局如

 from flask import request