繁体   English   中英

无法使用flask.g访问其他函数中的变量

[英]Unable to use flask.g to access variables in other functions

我正在尝试使用flask.g来存储可以在其他函数中访问的变量,但我似乎没有正确地执行某些操作。 当我尝试访问g.name时,应用程序生成以下错误: AttributeError: '_RequestGlobals' object has no attribute 'name'

flask.g文档说:

只要存储在你想要的任何东西上。 例如,数据库连接或当前登录的用户。

这是一个完整的,最小的例子,它说明了我在尝试访问创建函数之外的变量时收到的错误。任何帮助都将非常感激。

#!/usr/bin/env python

from flask import Flask, render_template_string, request, redirect, url_for, g
from wtforms import Form, TextField

application = app = Flask('wsgi')

@app.route('/', methods=['GET', 'POST'])
def index():
    form = LoginForm(request.form)

    if request.method == 'POST' and form.validate():
        name =  form.name.data
        g.name = name

        # Need to create an instance of a class and access that in another route
        #g.api = CustomApi(name)

        return redirect(url_for('get_posts'))

    else:

        return render_template_string(template_form, form=form)

@app.route('/posts', methods=['GET'])
def get_posts():
    # Need to access the instance of CustomApi here
    #api = g.api
    name = g.name
    return render_template_string(name_template, name=name)


class LoginForm(Form):
    name = TextField('Name')

template_form = """
{% block content %}
<h1>Enter your name</h1>

<form method="POST" action="/">
    <div>{{ form.name.label }} {{ form.name() }}</div><br>
    <button type="submit" class="btn">Submit</button>    
</form>
{% endblock %}

"""

name_template = """
{% block content %}

    <div>"Hello {{ name }}"</div><br>

{% endblock %}

"""

if __name__ == '__main__':
    app.run(debug=True)

g对象是一个基于请求的对象,不会在请求之间保持不变,即在您的index请求和get_posts请求之间重新创建g

应用程序Globals在Flask中

Flask为您提供了一个特殊对象,确保它仅对活动请求有效,并为每个请求返回不同的值 简而言之:它做的是正确的,就像它对请求和会话一样。

对于在请求之间持久存储微小数据,请使用sessions 您可以(但不应该)直接将app对象中的数据存储到全局(所有会话)应用程序状态,类似于config ,如果您找到了一个非常好的理由。

对于更复杂的数据使用数据库。

如果您需要跟踪身份验证信息,我建议使用其中一个Flask插件,如Flask-LoginFlask-Principal

例如,我们使用Flask-Principal。 当某人进行身份验证时(或者它检测到身份验证cookie),它会引发加载身份的信号。 然后,我们将他们的登录身份映射到我们数据库中的用户。 像这样的东西:

# not actual code
@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
  user = Person.query.filter(Person.username==identity.person.username).one()
  g.user = user

然后我们可以在任何控制器或模板中使用g.user。 (我们实际上已经把这很多东西剥掉了,这是一个简单,懒惰的黑客,它造成的麻烦超过它的价值。)

如果您不想使用模块,可以在每个请求开始时挂入一个内置信号:

http://flask.pocoo.org/docs/tutorial/dbcon/

# This runs before every request
@app.before_request
def before_request():
    g.user = your_magic_user_function()

然后g.user将会无处不在。

我希望有所帮助!

只需在烧瓶中使用会话。 在您的情况下,您只想在请求中保存用户/名称,最简单的方法是使用会话。

from flask import session
app.secret_key = 'some key for session'

然后,您的功能可以更改如下:

@app.route('/', methods=['GET', 'POST'])
def index():
    form = LoginForm(request.form)
    if request.method == 'POST' and form.validate():
        session['name'] =  form.name.data
        return redirect(url_for('get_posts'))
    else:
        return render_template_string(template_form, form=form)

@app.route('/posts', methods=['GET'])
def get_posts():
    if 'name' in session:
        name = session['name']
    else:
        name = "Unknown"
    return render_template_string(name_template, name=name)

暂无
暂无

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

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