63

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'

それ以外の場合、ログインは正常に機能します。私は何が欠けていますか?

4

3 に答える 3

82

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
于 2012-11-29T17:40:32.843 に答える
13

マイナーな修正ですが、gオブジェクトはリクエストコンテキストではなくアプリケーションコンテキストにバインドされるようになりました。

「Flask0.10以降、これはアプリケーションコンテキストに保存され、リクエストコンテキストには保存されなくなります。つまり、アプリケーションコンテキストのみがバインドされ、まだリクエストがない場合に使用可能になります。」

于 2015-10-08T03:20:39.760 に答える
-29

私はグローバルをすべて一緒に取り除こうとします。アプリケーションをタスクを実行する関数のセットと考えてください。各関数には入力と出力があり、グローバルに触れないようにする必要があります。ユーザーを取得して渡すだけで、コードのテストがはるかに容易になります。さらに良いこと:フラスコを取り除く、フラスコは次のようなグローバルの使用を促進します

from flask import request
于 2016-02-10T15:11:41.660 に答える