模板文件更改时重新加载Flask应用


95

默认情况下,使用内置服务器(Flask.run)运行Flask应用程序时,它将监视其Python文件并在代码更改时自动重新加载该应用程序:

* Detected change in '/home/xion/hello-world/app.py', reloading
* Restarting with reloader

不幸的是,这似乎仅适用于* .py文件,而且我似乎没有找到任何将此功能扩展到其他文件的方法。最值得注意的是,当模板更改时,让Flask重新启动应用程序将非常有用。我已经迷失了多少次我不喜欢模板中的标记,却因为看不到任何更改而感到困惑,只是发现该应用程序仍在使用旧版本的Jinja模板。

因此,有没有办法在模板目录中包含Flask监视文件,还是需要深入研究框架的源代码?

编辑:我正在使用Ubuntu 10.10。尚未在任何其他平台上尝试过。


经过进一步的查询,我发现模板中的更改确实实时更新的,而无需重新加载应用程序本身。但是,这似乎仅适用于传递给的模板flask.render_template

但是碰巧的是,在我的应用程序中,我有很多在Jinja模板中使用的可重用的,参数化的组件。它们实现为{% macro %}s,驻留在专用的“模块”中,并{% import %}编入实际页面。很好,很干...除了那些导入的模板显然从未检查过是否修改,因为它们根本没有通过render_template

(奇怪的是,对于通过调用的模板,这种情况不会发生{% extends %}。至于{% include %},由于不真正使用它们,我不知道。)

因此,总结起来,这种现象的根源似乎在Jinja和Flask或Werkzeug之间。我想对于其中的任何一个项目,都可能需要进行bug跟踪:)同时,我已经接受了jd。的答案,因为这是我实际使用的解决方案-而且它的工作原理很像魅力。


3
确保应用配置为DEBUG = True,请参阅docs
亚历克斯·莫雷加

Answers:


65

以我的经验,模板甚至不需要重新启动应用程序即可刷新,因为每次render_template()调用时都应从磁盘加载模板。也许您的模板使用方式有所不同。

要在模板更改(或其他文件)时重新加载应用程序,可以将extra_files参数传递给Flask().run(),以观察文件名的集合:这些文件上的任何更改都会触发重新加载器。

例:

from os import path, walk

extra_dirs = ['directory/to/watch',]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
    for dirname, dirs, files in walk(extra_dir):
        for filename in files:
            filename = path.join(dirname, filename)
            if path.isfile(filename):
                extra_files.append(filename)
app.run(extra_files=extra_files)

参见此处:http : //werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple


好东西!我承认我错过了Flask.run导致Werkzeug文档的文档中的链接。但是,此特定选项似乎很有用,至少足以在Flask文档中提及它。
Xion 2012年

如果有人遇到错误提示No such file or directory,请尝试使用相对路径,如下所示:extra_dirs = ['./directory/to/watch',]
Kevin Kevin

3
如果您也对什么感到困惑path,那就是os.path。认为值得一提
耶稣基督

有关在更改静态文件后自动重新加载的信息,请参见this
simanacci

1
flask run从命令行运行时如何指定额外的文件?
Michael Scheper

143

您可以使用

TEMPLATES_AUTO_RELOAD = True

http://flask.pocoo.org/docs/1.0/config/

是否检查模板源的修改并自动重新加载。默认情况下,该值为“无”,这意味着Flask仅在调试模式下检查原始文件。


11
该解决方案是常规的,有文档支持,易于理解,易于实施。应该接受!
卡罗琳·康威

我尝试了这个答案,但只工作一次,一次又一次刷新将不起作用
medev21 '16

3
只是对其他人的注释:我做了app.config['TEMPLATES_AUTO_RELOAD'] = True,并且由于某种原因,期望在模板更改时看到服务器自动重启,就像在调试模式下一样。它不会重新启动,但是会更新它呈现的模板。
cs01

3
有什么原因不能在0.12下工作?或其他一些设置会阻止此设置的正确设置?
user805981

3
@Federer它似乎不像以前那样工作...以前,它会检测到模板目录和子目录中的更改并会重新加载服务器...。这是0.12中的新功能吗?改变了?
user805981

54

使用jinja模板时,需要设置一些参数。就python3而言,我使用以下代码解决了它:

if __name__ == '__main__':
    app.jinja_env.auto_reload = True
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(debug=True, host='0.0.0.0')

1
你救了我的理智。谢谢。
Nostalg.io

我也很难解决这个问题。我很高兴能为您提供帮助;)
silgon

这对我来说是烧瓶1.0.2上的工作,但我没有host参数。
恩里科·博尔巴

是的@EnricoBorba,您可能不需要它。我之所以使用它,是因为我使用docker在本地进行调试,有时需要从另一个容器访问该应用程序。一些参考
silgon

@silgon是的,我明白。我主要是在添加评论以明确说明在全新安装的Flask版本1.0.2中起作用的原因
Enrico Borba


10

实际上对我来说TEMPLATES_AUTO_RELOAD = True不起作用(0.12版本)。我使用jinja2和我所做的事情:

  1. 创建功能 before_request

    def before_request():
        app.jinja_env.cache = {}
  2. 在应用程序中注册

    app.before_request(before_request)
  3. 而已。


3
Garret,如果没有这些选项,我不会进行测试。
dikkini

步骤3并不是真正必要的,对我来说效果很好。
里卡多·里贝罗

4

对我有用的只是添加以下内容:

@app.before_request
def before_request():
    # When you import jinja2 macros, they get cached which is annoying for local
    # development, so wipe the cache every request.
    if 'localhost' in request.host_url or '0.0.0.0' in request.host_url:
        app.jinja_env.cache = {}

摘自@dikkini的回答


2

在Windows上使用最新版本的Flask,并将run命令和debug设置为true;无需重置Flask即可生效对模板的更改。尝试按Shift + F5(或Shift加重新加载按钮)以确保没有任何内容被缓存。



1

截至2019年6月更新:

建议在app.run()上使用烧瓶CLI,以运行开发服务器,因此,如果我们要使用CLI,则不能使用接受的解决方案。

在撰写本文时,使用Flask(1.1)的开发版本允许我们设置环境变量FLASK_RUN_EXTRA_FILES,该变量有效地执行与接受的答案相同的操作。

请参阅此github问题

用法示例:

export FLASK_RUN_EXTRA_FILES="app/templates/index.html"
flask run

在Linux中。要指定多个其他文件,请使用冒号分隔文件路径。,例如

export FLASK_RUN_EXTRA_FILES="app/templates/index.html:app/templates/other.html"

CLI还支持--extra-filesFlask 1.1以后的参数。


小更新。链接到“ flask CLI”的链接需要更新到当前版本。 flask.palletsprojects.com/en/1.1.x/cli 否则,谢谢:)
CodingMatters

1

模板会自动重新加载,为什么不ctrl+f5刷新网页,导致Web浏览器通常保存缓存。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.