Подтвердить что ты не робот

Как использовать глобальную в колбе g.user

Насколько я понимаю переменную g в Flask, она должна предоставить мне глобальное место для хранения данных, таких как сохранение текущего пользователя после входа в систему. Правильно ли это?

Я бы хотел, чтобы моя навигация отображала мое имя пользователя после входа в систему через сайт.

Мои представления содержат

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'

В противном случае логин работает нормально. Что мне не хватает?

4b9b3361

Ответ 1

g является нить локальной и является для каждого запроса (см. Примечание о прокси-серверах), session также является потоком локальным, но в контексте по умолчанию сохраняется файл cookie с MAC-адресом и отправляется клиенту.

Проблема, с которой вы столкнулись, заключается в том, что session перестраивается по каждому запросу (поскольку он отправляется клиенту, а клиент отправляет его нам), а набор данных на g доступен только для время жизни этого запроса.

Простейшая вещь (обратите внимание simple != secure - если вам нужно безопасно взглянуть на Flask-Login), просто добавьте идентификатор пользователя на сеанс и загружать пользователя по каждому запросу:

@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

Ответ 2

Незначительная коррекция, g-объект привязан к контексту приложения теперь вместо контекста запроса.

"Начиная с Flask 0.10 это сохраняется в контексте приложения и больше не находится в контексте запроса, что означает, что он становится доступным, если привязан только контекст приложения и еще не запрос" .

Ответ 3

Я попытался бы избавиться от глобальных комбинаций, подумайте о своих приложениях как о наборе функций, которые выполняют задачи, каждая функция имеет входы и выходы и не должна касаться глобальных. Просто принесите своего пользователя и передайте его, это сделает ваш код намного более проверяемым. Еще лучше: избавиться от колбы, фляжка продвигается с использованием глобалов, таких как

from flask import request