简体   繁体   English

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

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

As I understand the g variable in Flask, it should provide me with a global place to stash data like holding the current user after login.据我了解 Flask 中的 g 变量,它应该为我提供一个全局位置来存储数据,例如在登录后保存当前用户。 Is this correct?这样对吗?

I would like my navigation to display my user's name, once logged in, across the site.我希望我的导航能够在登录后在整个站点上显示我的用户名。

My views contain我的观点包含

from Flask import g #among other things

During login, I assign在登录期间,我分配

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

It doesn't seem I can access g.user.我似乎无法访问 g.user。 Instead, when my base.html template has the following...相反,当我的 base.html 模板具有以下内容时...

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

I get the error:我收到错误:

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

The login otherwise works fine.否则登录工作正常。 What am I missing?我错过了什么?

g is a thread local and is per-request (See A Note On Proxies ). g是一个本地线程并且是针对每个请求的(请参阅代理的注释)。 The session is also a thread local, but in the default context is persisted to a MAC-signed cookie and sent to the client. session也是本地线程,但在默认上下文中被持久化到 MAC 签名的 cookie 并发送到客户端。

The problem that you are running into is that session is rebuilt on each request (since it is sent to the client and the client sends it back to us), while data set on g is only available for the lifetime of this request.您遇到的问题是每次请求都会重建session (因为它被发送到客户端,然后客户端将其发送回我们),而g上的数据集仅在请求的生命周期内可用。

The simplest thing to do (note simple != secure - if you need secure take a look at Flask-Login ) is to simply add the user's ID to the session and load the user on each request:要做的最简单的事情(注意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

I would try to get rid of globals all together, think of your applications as a set of functions that perform tasks, each function has inputs and outputs, and should not touch globals.我会尽量摆脱全局变量,将您的应用程序视为一组执行任务的函数,每个函数都有输入和输出,并且不应该接触全局变量。 Just fetch your user and pass it around, it makes your code much more testable.只需获取您的用户并传递它,它会使您的代码更具可测试性。 Better yet: get rid of flask, flask promotes using globals such as更好的是:摆脱烧瓶,烧瓶促进使用全局变量,例如

from flask import request

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

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