繁体   English   中英

如何在烧瓶中使用 g.user global

[英]How to use g.user global in flask

据我了解 Flask 中的 g 变量,它应该为我提供一个全局位置来存储数据,例如在登录后保存当前用户。 这样对吗?

我希望我的导航能够在登录后在整个站点上显示我的用户名。

我的观点包含

from Flask import g #among other things

在登录期间,我分配

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'

否则登录工作正常。 我错过了什么?

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

您遇到的问题是每次请求都会重建session (因为它被发送到客户端,然后客户端将其发送回我们),而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

我会尽量摆脱全局变量,将您的应用程序视为一组执行任务的函数,每个函数都有输入和输出,并且不应该接触全局变量。 只需获取您的用户并传递它,它会使您的代码更具可测试性。 更好的是:摆脱烧瓶,烧瓶促进使用全局变量,例如

from flask import request

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM