Flask访问设置页报Jinja2 UndefinedError及404错误求助
错误1:jinja2.exceptions.UndefinedError: 'user' is undefined 根因
layout.html作为全局母版会被所有页面继承,你只有user路由渲染settings.html时才给模板传了user变量,其他路由渲染页面时没有传递该变量,就会触发未定义报错。你改用g.user后报错消失,说明你已经通过请求钩子/上下文处理器把当前登录用户存入了应用上下文g,这部分逻辑没有问题。
错误2:设置页返回404根因
你修改后的链接代码传入的是Users_username=g.user,这里传递的是完整的用户对象,而非用户名字符串,url_for生成URL时会自动把对象转为默认字符串格式(例如<Users object 1>),和数据库中存储的username完全不匹配,查询不到对应用户就会触发404。
另外要注意你贴出的routes.py代码存在缩进错误,Python对缩进敏感,函数体内的代码如果没有正确缩进会完全不生效。
修复步骤
- 修正layout.html的链接传参,取
g.user的username属性传入:
<a href="{{ url_for('user', Users_username=g.user.username) }}" target="_blank" rel="noopener noreferrer">Settings</a>
- 修正routes.py中user路由的缩进问题,确保函数体内所有代码都缩进对齐:
@app.route("/user/<Users_username>" , methods=["GET", "POST"]) def user(Users_username): user = Users.query.filter_by(username=Users_username).first() if user is None: flash("该用户不存在") return redirect(url_for('register')) return render_template("settings.html", user=user)
- 可选优化:增加未登录场景判断,避免用户未登录时
g.user为空触发报错:
{% if g.user %} <a href="{{ url_for('user', Users_username=g.user.username) }}" target="_blank" rel="noopener noreferrer">Settings</a> {% else %} <a href="{{ url_for('login') }}">登录</a> {% endif %}
如果你使用了Flask-Login扩展的话,可以直接用框架默认提供的全局current_user对象,无需自己维护g.user,直接将参数替换为current_user.username即可,Flask-Login会自动将current_user注入所有模板上下文,不需要单独传参。
内容的提问来源于stack exchange,提问作者Talal Iqbal
相关产品推荐
相关产品推荐

