2012-12-07 13 views
5

flask.gを使用して他の関数でアクセスできる変数を格納しようとしていますが、正しく動作していないようです。 g.nameにアクセスしようとすると、アプリケーションで次のエラーが生成されます。AttributeError: '_RequestGlobals' object has no attribute 'name'フラスコを使用して他の関数の変数にアクセスすることができません

flask.gためdocumentationは言う:

はちょうどあなたが好きな本に格納します。たとえば、データベース 接続または現在ログインしているユーザー。

は、ここでそれが作成された関数の外の変数にアクセスしようとしたとき、私は受信エラーを示し、完全な、最小限の例です。どれ助けていただければ幸いです。

#!/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) 

答えて

2

認証情報を追跡する必要がある場合は、Flask-LoginまたはFlask-PrincipalのようなFlaskプラグインの1つをお勧めします。

たとえば、Flask-Principalを使用します。誰かが認証する(または認証クッキーを検出する)と、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は、どこでも魔法利用できるようになります。

私はそれが助けてくれることを願っています!

+0

私の場合、@ app.before_requestを使用する際の問題は、私がmagic_user_function()を利用するためにユーザからユーザ名とパスワード情報を取得する必要があることです。私があなたが言及したモジュールをチェックアウトします。 – Raj

+0

私はフォローアップして、これが私のやり遂げたことであることを知らせます。私はこのメソッドをサポートするためにラッパーを書き直さなければならなかったが、それほど悪くはなかった。私のフラスコの質問btwレイチェルの答えをありがとう! – Raj

13

gオブジェクトは、要求ベースのオブジェクトであり、すなわちgindexするリクエストとget_postsにリクエストの間に再作成され、要求の間持続しません。

Application Globals in Flask

フラスコはがアクティブな要求に対してのみ有効であり、それは各要求に異なる値を返すことが保証されます特別なオブジェクトを提供します。一言で言えば、リクエストやセッションの場合と同様に、正しいことです。

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

もっと複雑なデータ使用データベースの場合。

+1

私は単純な変数のような情報の小さなビットのためのあなたの答えを理解し、どのように私はクラスのインスタンスを作成しないと全体であることを共有します複数の機能?具体的には、認証情報を返すクラスのインスタンスを作成しています。返されたデータを複数のルートで使用したいと思います。 – Raj

+0

セッション間でオブジェクトを再構築するために 'session'を使うのが一番簡単な方法でしょう。 'user_id'を格納するのと同じように、おそらく。シリアライゼーションも機能します。最低限のオーバーヘッドと可読性とセンスを備えたメソッドを選択します。 – soulseekah

+1

@Rajこれは、g.usersがなぜあなたのためにうまくいかなかったのかを定義するので、受け入れられる答えでなければなりません。 –

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) 
関連する問題