10

他の関数でアクセスできる変数を格納するために使用しようとして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)
4

4 に答える 4

19

gオブジェクトはリクエストベースのオブジェクトであり、リクエスト間で保持されません。つまり、 へのリクエストと へのgリクエストの間で再作成されます。indexget_posts

Flask のアプリケーション グローバル:

Flask は、アクティブなリクエストに対してのみ有効であり、リクエストごとに異なる値を返す特別なオブジェクトを提供します。一言で言えば、リクエストとセッションの場合と同様に、正しいことを行います。

リクエスト間の小さなデータの永続的なストレージには、sessions代わりに使用します。本当に正当な理由が見つかった場合appと同様に、グローバル (すべてのセッション) アプリケーション状態のデータをオブジェクトに直接格納することで回避できます (ただしすべきではありません) 。config

より複雑なデータには、データベースを使用します。

于 2012-12-07T05:33:26.990 に答える
3

認証情報を追跡する必要がある場合は、Flask-LoginFlask-Principalなどの Flask プラグインのいずれかをお勧めします。

たとえば、Flask-Principal を使用します。誰かが認証したとき (または認証 Cookie を検出したとき) に ID 読み込みシグナルを発生させます。次に、ログイン ID をデータベース内のユーザーにマップします。このようなもの:

# 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 は魔法のようにどこでも利用できるようになります。

それが役立つことを願っています!

于 2012-12-07T06:26:08.147 に答える
1

フラスコでセッションを使用するだけです。あなたの場合、リクエストにユーザー/名前を保存したいだけで、最も簡単な方法はセッションを使用することです。

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)
于 2012-12-07T16:24:09.310 に答える