我有一个带蓝图的Flask应用。每个蓝图都提供了一些模板。当我尝试从第二个蓝图渲染index.html
模板时,会渲染第一个蓝图的模板。为什么blueprint2会覆盖blueprint1的模板?如何渲染每个蓝图的模板?
app/
__init__.py
blueprint1/
__init__.py
views.py
templates/
index.html
blueprint2/
__init__.py
views.py
templates/
index.html
blueprint2/__init__.py
:
from flask import Blueprint
bp1 = Blueprint('bp1', __name__, template_folder='templates', url_prefix='/bp1')
from . import views
blueprint2/views.py
:
from flask import render_template
from . import bp1
@bp1.route('/')
def index():
return render_template('index.html')
app/__init__.py
:
from flask import Flask
from blueprint1 import bp1
from blueprint2 import bp2
application = Flask(__name__)
application.register_blueprint(bp1)
application.register_blueprint(bp2)
如果我更改了蓝图的注册顺序,那么blueprint2的模板会覆盖蓝图1。
application.register_blueprint(bp2)
application.register_blueprint(bp1)
答案 0 :(得分:5)
这与预期完全一致,但并不像您期望的那样。
为蓝图定义模板文件夹只会将文件夹添加到模板搜索路径中。它不意味着从蓝图的视图中调用render_template
只会检查该文件夹。
首先在应用程序级别查找模板,然后按顺序查找蓝图。这样,扩展可以提供可以被应用程序覆盖的模板。
解决方案是在模板文件夹中使用单独的文件夹,以获取与特定蓝图相关的模板。它仍然可以覆盖它们,但更难以意外地这样做。
app/
blueprint1/
templates/
blueprint1/
index.html
blueprint2/
templates/
blueprint2/
index.html
render_template('blueprint1/index.html')
有关详细讨论,请参阅Flask issue #1361。
答案 1 :(得分:-1)
我依稀记得很早就遇到过这样的问题。您尚未发布所有代码,但我根据您编写的内容提出了四条建议。尝试第一个,测试它,然后如果它仍然不起作用,尝试下一个,但独立测试它们,看看它们是否有效:
首先,我看不到您的views.py
文件,因此请务必在views.py
个文件中导入相应的蓝图:
from . import bp1 # in blueprint1/views.py
from . import bp2 # in blueprint2/views.py
其次,您可能需要修复__init__.py
中的相对import语句,如下所示(注意子文件夹之前的句点):
from .blueprint1 import blueprint1 as bp1
from .blueprint2 import blueprint2 as bp2
第三,由于您在render_template
函数中对模板的路径进行了硬编码,请尝试从蓝图定义中删除template_folder='templates'
。
第四,看起来您在注册时将蓝图的url_prefix命名为“/ bp1”。因此,如果到您的文件系统的硬编码链接仍然不起作用:
render_template('blueprint1/index.html')
然后尝试这个,看看会发生什么:
render_template('bp1/index.html')
同样,我看不到你的完整代码,但我希望这会有所帮助。