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

Xio*_*ion 78 python jinja2 flask

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

* Detected change in '/home/xion/hello-world/app.py', reloading
* Restarting with reloader
Run Code Online (Sandbox Code Playgroud)

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

那么,有没有办法让Flask监控文件存在于模板目录中,还是需要深入到框架的源代码?

编辑:我正在使用Ubuntu 10.10.没有在任何其他平台上尝试过.


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

但实际上,在我的应用程序中,我有很多可重复使用的参数化组件,我在Jinja模板中使用它们.它们被实现为{% macro %}s,驻留在专用的"模块"中并被{% import %}编入实际页面.所有不错和DRY ...除了那些导入的模板显然从未检查过修改,因为它们根本没有通过render_template.

(奇怪的是,对于通过调用的模板,这不会发生{% extends %}.至于{% include %},我不知道,因为我没有真正使用它们.)

总而言之,这种现象的根源似乎介于Jinja和Flask或Werkzeug之间.我想这可能需要为这些项目之一的bug追踪者旅行:)同时,我接受了jd.的回答是因为这是我实际使用的解决方案 - 而且它就像一个魅力.

小智 114

您可以使用

TEMPLATES_AUTO_RELOAD = True
Run Code Online (Sandbox Code Playgroud)

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

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

  • 该解决方案是传统的,由文档支持,易于理解且易于实现.应该被接受! (7认同)
  • 只是对其他人的说明:我做了`app.config['TEMPLATES_AUTO_RELOAD'] = True`,并且出于某种原因希望在模板更改时看到服务器自动重启,就像在调试模式下一样。它不会重新启动,但会更新它呈现的模板。 (5认同)
  • 为什么这不适用于0.12?或其他一些设置,以防止这种情况正确设置? (3认同)
  • @Federer它似乎没有像以前一样工作......以前,它会检测到模板目录和子目录中的更改,它会重新加载服务器....这是0.12中的新内容改变了吗? (3认同)

jd.*_*jd. 55

根据我的经验,模板甚至不需要重新启动应用程序来刷新,因为它们应该在每次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)
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你也对`path`是什么感到困惑,那就是`os.path`.以为值得一提 (2认同)
  • 知道如何在从命令行运行“flask run”时指定额外文件吗? (2认同)

sil*_*gon 38

使用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')
Run Code Online (Sandbox Code Playgroud)


dik*_*ini 9

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

  1. 创建功能 before_request

    def before_request():
        app.jinja_env.cache = {}
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在申请中注册

    app.before_request(before_request)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 而已.

  • 我认为第3步是不必要的,对吧? (3认同)
  • 加勒特,没有这些选择,我没有测试. (3认同)

Nik*_*hal 7

对我来说效果很好:

 from flask import Flask, render_template, request, url_for, redirect
 app = Flask(__name__)
 app.config["TEMPLATES_AUTO_RELOAD"] = True
Run Code Online (Sandbox Code Playgroud)

请参阅http://flask.pocoo.org/docs/1.0/config/


Gar*_*ett 5

对我有用的只是添加这个:

@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 = {}
Run Code Online (Sandbox Code Playgroud)

摘自@dikkini的回答


小智 5

截至 2021 年 3 月更新:

推荐使用flask CLI而不是app.run() 来运行开发服务器,因此如果我们想使用CLI,则不能使用已接受的解决方案。

在 Flask 1.1 或更高版本中,环境变量FLASK_RUN_EXTRA_FILES或选项--extra-files有效地与接受的答案做同样的事情。另请参阅此 github 问题

用法示例:

flask run --extra-files "app/templates/index.html"
# or
export FLASK_RUN_EXTRA_FILES="app/templates/index.html"
flask run
Run Code Online (Sandbox Code Playgroud)

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

export FLASK_RUN_EXTRA_FILES="app/templates/index.html:app/templates/other.html"
Run Code Online (Sandbox Code Playgroud)

还支持整个目录:

flask run --extra-files app/templates/
Run Code Online (Sandbox Code Playgroud)


Hyp*_*ive 5

为了在服务器和浏览器中重新加载应用程序,我使用了该livereload包。通过 CLI 安装

$ pip install livereload
Run Code Online (Sandbox Code Playgroud)

并运行代码

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def hello():
    return render_template("index.html")

if __name__ == '__main__':
    from livereload import Server
    server = Server(app.wsgi_app)
    server.serve(host = '0.0.0.0',port=5000)
Run Code Online (Sandbox Code Playgroud)

这里使用extra_files参数或TEMPLATES_AUTO_RELOAD配置的所有答案都可以将其重新加载到服务器上,但为了获得顺利的开发体验而不损坏键盘的 F5 键,我会选择livereload