Flask中的全局变量不一致

时间:2015-08-11 13:14:10

标签: python session flask jinja2

我有一个菜单,用户可以根据自己的权限查看不同的菜单项。我在登录时检查用户是否有选项,将其存储在全局变量中,并在渲染菜单时检查该变量。

在制作中,菜单仅在50%的时间内正确显示。有时设置值,有时它是空的。为什么这不正常?

@app.route('/login/', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        user = User.get(request.form['username'])

        if user.user is None:
            return redirect('/login/')

        if user and check_password_hash(user.user.password, request.form['password']):
            login_user(user)
            if isinstance(current_user.user, UserTypeOne):
                group = UserGroup.query.filter_by(id=int(current_user.user.group)).first()
                app.jinja_env.globals['group_access_to_feature_one'] = group.group_access_to_feature_one

            return redirect(request.args.get('next') or url_for('index'))

        return redirect(url_for('login'))

header模板有条件检查该值:

{% if group_access_to_feature_one%}<ul>...</ul>{%endif%}

调试时,我会{{ group_access_to_feature_one }}查看该值,有时会True,有时它会为空。

1 个答案:

答案 0 :(得分:3)

在生产中(有时可能在dev上),您正在运行多个进程。每个进程都会创建自己的应用程序副本,因此只有处理登录请求的进程中的应用程序才会看到对env的更改。这是不鼓励使用Python全局变量来存储状态的主要原因之一。 app.jinja_env.globals仅在设置期间进行修改,以便每个进程/线程保持一致。

使用数据库或其他存储(如redis)来存储和访问全局状态。使用session存储有关特定浏览器会话的信息,例如登录用户。使用app.before_request回调为每个请求加载每个用户的状态。

您的代码也不正确,因为每次用户登录时都会更改全局Flask环境。因此每个用户的值的值将基于 last 用户登录并设置值。