我目前正在开发一个Flask应用程序(已经过去一年)并且我遇到了一个相当......奇怪的错误。我有一些文件总是包含在我的Jinja2模板(navbars)中,它们使用用户的名字和头像。因此,每次我渲染模板时,我都会将其传递给用户。我最近在我的prod服务器上发现了一个错误:
<img alt="image" class="img-circle" src="{{ user.image }}" style="width: 48px;"/>
File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 397, in getattr
return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'user' is undefined
这是在我的一个导航栏中。呈现此模板的方法使用此方法:
@mod.route('/broken_pus', methods=['POST', 'GET'])
def view_broken_pus():
return render_template("view_broken_pus.html", user=g.user, urls_for_active_clients=DeletedURLs.objects()[0].urls_for_active_clients, other_urls=DeletedURLs.objects()[0].other_urls)
如您所见,我传递了user = g.user。我在我的网站的每个视图上都这样做。它适用于所有地方,除了这个方法,这是非常小的。我有很多其他类似的路线,只有一个渲染模板,所以我没有得到什么问题。
我也接受了另一种更大的方法,它始终有效:
@mod.route('/users/add', methods=['GET', 'POST'])
@requires_roles("admin", "project-leader")
def add():
"""
Method adding a new user.
"""
# We do not use WTForms there since we need custom checkboxes for the role
# Instead we use basic HTML and treat the checkboxes here
if request.method == 'POST':
user = User(name=request.form.get('name'),
email=request.form.get('email'))
l = []
# big switch assignement
user.role = l
try:
user.save()
except errors.NotUniqueError:
flash(u'User %s already in database.' % user.name, 'danger')
return redirect(url_for('home'))
flash(u'User %s registered.' % user.name, 'success')
return redirect(url_for('home'))
return render_template('add_user.html', page=url_for('users.add'), user=g.user, clients=Client.objects())
当我第一次加载表单以添加用户时,它可以正常工作。当我添加它时,由于某种原因,我收到错误(并且用户未保存在数据库中)。
由于这在本地完美运行,我开始怀疑生产服务器本身存在问题。我们为应用程序使用nginx和uwsgi,最近我实现了一些Celery任务。知道吗?
提前致谢。
答案 0 :(得分:0)
我怀疑是穿线。如果g是某种全局引用,那么你可能需要确保在threading.local上设置它,或者使用线程锁来确保在某些“其他”线程混乱之前没有线程可以获取g.user
在不牺牲线程安全的情况下,查看how do I make a 2.7 python context manager threadsafe处理'全局变量'的方法。