web-dev-qa-db-fra.com

Comment utiliser g.user global dans flask

Si je comprends bien la variable g dans Flask, elle devrait me fournir un emplacement global pour stocker des données comme le maintien de l'utilisateur actuel après la connexion. Est-ce correct?

Je souhaite que ma navigation affiche le nom de mon utilisateur, une fois connecté, sur le site.

Mes vues contiennent

from Flask import g #among other things

Lors de la connexion, j'attribue

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

Il ne semble pas que je puisse accéder à g.user. Au lieu de cela, lorsque mon modèle base.html présente les éléments suivants ...

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

Je reçois l'erreur:

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

La connexion fonctionne sinon correctement. Qu'est-ce que je rate?

55
Mittenchops

g est un thread local et est par demande (Voir A Note On Proxies ). session est également un thread local, mais dans le contexte par défaut est conservé dans un cookie signé MAC et envoyé au client.

Le problème que vous rencontrez est que session est reconstruit à chaque demande (car il est envoyé au client et que le client nous le renvoie), tandis que le jeu de données sur g est uniquement disponible pour la durée de vie de cette demande.

La chose la plus simple à faire (notez simple != secure - si vous avez besoin de sécurité, jetez un œil à Flask-Login ) consiste simplement à ajouter l'ID de l'utilisateur à la session et à charger l'utilisateur à chaque demande:

@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
75
Sean Vieira
11
AlexLordThorsen