我是一个十足的Flask/Jinja2新手,所以也许我忽略了一些显而易见的东西,但是:
Flask不应该开箱即用,允许blueprint的templates/
文件夹中的模板扩展由我的应用程序的templates/
文件夹定义的基本模板吗?即使蓝图还包含一个“默认”的基本模板,我通过定义自己的同名基础模板来覆盖它,这难道不起作用吗?在
对this other SO question的回答让我认为这两件事绝对应该是这样。特别是答案中说:
If there are two templates with same name[, one] in app's templates folder and [the other in] blueprint's template folder, then template in app's templates folder will get priority.
但这对我来说根本不起作用。事实上,它的工作方式似乎与相反,也就是说,蓝图中的base.html
被我的应用程序中定义的页面拖入,即使我的应用程序定义了自己的base.html
(如果上面的答案是正确的,它应该“获得优先权”)。在
在我的应用程序中,我有:
myapp/
templates/
base.html
pages/
page_base.html
home_page.html
其中pages/home_page
扩展{
我还使用PyPI中的flask_user
包,它是由pip
安装在/usr/local/lib/python2.7/dist-packages/flask_user/
上的。其模板文件夹的排列如下:
此包通过蓝图使使用它的应用程序可以使用它的模板,它在其UserManager
类(^{init_app
函数中建立了一个蓝图:
# Add flask_user/templates directory using a Blueprint
blueprint = Blueprint('flask_user', 'flask_user', template_folder='templates')
app.register_blueprint(blueprint)
我最初的想法是,通过定义我自己的myapp/templates/base.html
,我就可以自定义从flask_user/templates/flask_user/
中呈现的页面,使其看起来像我的应用程序中的其他页面,因为(根据引用的答案),我的base.html
应该优先于flask_user
base.html
。在
但这不起作用,更糟糕的是,更令人惊讶的是,我的应用程序页面的默认外观是flask_user
。在
深入挖掘…
根据@Pralhad Narsinh Sonar的建议,模板搜索路径的排序可能有问题,这可能是由DispatchingJinjaLoader._iter_loaders()
的不确定性行为引起的,正如他引用的fewstreet.com article所建议的,我做了一个快速的实验,看看_iter_loaders()
会对我的应用程序产生什么样的排序:
>>> from myapp.top import app, db
>>> from myapp.startup import init_app.init_app
>>> init_app(app, db)
>>> app.jinja_env.loader
<flask.templating.DispatchingJinjaLoader object at 0x7f233e396dd0>
>>> for loader in app.jinja_env.loader._iter_loaders('pages/home_page.html') :
... print loader, loader.searchpath
...
<jinja2.loaders.FileSystemLoader object at 0x7f233eb08490> ['/var/www/python/myapp/templates']
<jinja2.loaders.FileSystemLoader object at 0x7f233e36ef10> ['/usr/local/lib/python2.7/dist-packages/flask_user/templates']
正如预期的那样,迭代器首先为我的应用程序的templates/
文件夹首先生成,然后为flask_user/templates/
生成加载程序。事实上,_iter_loaders()
函数是经过精心设计的,在返回任何蓝图加载程序之前返回应用程序的加载程序。(如果我在读fewstreet.com网站文章正确,它关注的问题是多个蓝图之间的不确定性排序,因为我的应用程序只使用一个蓝图,这不是我当前的问题。)
这个结果使我更难理解为什么使用flask_user
的base.html
模板来解析我的模板的{% extends "base.html" %}
语句*。鉴于我在myapp/templates
中有自己的base.html
文件,我认为模板系统没有理由查看flask_user/templates
中的任何内容来呈现{
*出于测试目的,我去掉了上面提到的pages/page_base.html
的间接寻址。
很明显,有些事情出了问题,但是什么事?在
我还没有在flask/templating.py
或jinja2/loaders.py
中搜索足够的相关代码来理解为什么会发生这种情况以及如何发生。这是我第一次进入烧瓶,我希望我不需要。在
答案是:
一直以来,我都在用
debug=True
运行(并重新加载)我的应用程序。在这对于自动重新加载已更改的Python模块非常有用。在
但是对于改变了的模板?嗯。。。没那么多。在
在我的
home_page.html
模板中引入了一个断点,并使用Flask调试器回顾了几个堆栈帧之后,我发现Jinja2使用LRU缓存来存储(按名称)它已经解析的模板。在因为在已经加载了一个
flask_user
页面(login.html
)之后,我萌生了创建自己的base.html
模板的想法,而当我引入myapp/templates/base.html
时,缓存中已经有了一个名为base.html
的模板。在因此,我停止并重新启动了应用程序,现在我的}的{}都正确地继承了my}
home_page.html
和{base.html
,而不是{base.html
。我怀疑在我重启应用程序之前,我自己的base.html
从未被我的应用程序的模板加载器读取过。在这是一个相当重要的问题,我相信,对于新手来说,这是一个需要解决的问题。我就把这个留在这里,希望有一天它能帮助那些碰巧踏入这个陷阱的人。在
如果您可以共享代码的
blueprint
部分,将非常有帮助。这可能是由于搜索路径中出现故障导致的——它将第一行模板视为要显示的模板。为了避免这种情况,您可以始终唯一地重命名模板文件。如果出于任何限制或偏好,如果您想保持相同的名称,那么您可以尝试将模板文件保存在主模板文件夹的子目录下。在
你可以通过这个链接-http://flask.pocoo.org/docs/0.10/blueprints/
选项1
请尝试使用此文件夹结构-您还需要在
blueprints
-关于这个问题{/strong}
选项2
^{pr2}$在上面的结构中,每个模块都有自己的路由文件,即-
view.py
,因此单独的blueprint
配置以使每个功能模块化。在请看一下https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications
相关问题 更多 >
编程相关推荐