Как использовать глобальную в колбе 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'
В противном случае логин работает нормально. Что мне не хватает?
Ответы
Ответ 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