Flask配置两个Blueprint后访问指定路由渲染错误模板如何解决?
问题原因
- Flask的模板查找逻辑是按搜索路径顺序匹配,优先级为:全局templates目录 > 先注册的Blueprint的
template_folder目录 > 后注册的Blueprint的template_folder目录。你两个Blueprint下的模板文件名完全相同,且webBlueprint的注册顺序早于UIBlueprint,Flask匹配到web下的同名模板后就会直接返回,不会继续查找UI目录下的模板。 - 你没有对不同Blueprint的模板做命名空间隔离,Flask默认不会自动区分不同Blueprint下重名的模板文件,即便你配置了独立的
template_folder也会出现匹配冲突。
解决方法
推荐使用模板命名空间方案,从根源避免冲突:
- 在每个Blueprint的templates目录下,新增一层和Blueprint同名的子目录,调整后的目录结构如下:
你的项目根目录 ├── UI/ │ ├── static/ │ └── templates/ │ └── UI/ # 新增的命名空间目录 │ ├── create_password.html │ └── Alogin.html └── web/ ├── static/ └── templates/ └── web/ # 新增的命名空间目录 └── 你的web模板文件
- 修改
UIBlueprint路由中的渲染代码,加上命名空间前缀:
@UI.route('/dashboard', methods=['GET', 'POST']) def login(): usr = Admin.query.filter_by(username="admin").first() if not usr: if request.method == "POST": if 'passwrd' in request.form: # 无关业务逻辑代码 return render_template('UI/create_password.html') # 加命名空间前缀 ## 存在admin账号时触发以下逻辑 if request.method == 'POST': if request.form['passwrd']: ### 无关业务逻辑代码 return render_template('UI/Alogin.html') # 加命名空间前缀
如果不想调整目录结构,也可以临时修改Blueprint的注册顺序,把UI Blueprint的注册代码放到web Blueprint前面,但该方法不推荐,后续新增重名模板依然会出现冲突。
你也可以在项目启动时添加如下代码,打印所有模板搜索路径的顺序,确认匹配优先级是否符合预期:print(app.jinja_loader.searchpath)
内容的提问来源于stack exchange,提问作者packetsniffer
相关产品推荐
相关产品推荐

