繁体   English   中英

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

[英]Reload Flask app when template file changes

默认情况下,当使用内置服务器 ( 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 之间。 我想这可能需要为这些项目中的任何一个进行错误跟踪器之旅:)同时,我已经接受了jd。 的答案,因为那是我实际使用的解决方案 - 它就像一个魅力。

您可以使用

TEMPLATES_AUTO_RELOAD = True

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

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

根据我的经验,模板甚至不需要重新启动应用程序即可刷新,因为它们应该在每次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

当您使用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')

您需要在应用配置中将TEMPLATES_AUTO_RELOAD属性设置为True

from flask import Flask

app = Flask(__name__)
app.config["TEMPLATES_AUTO_RELOAD"] = True

http://flask.pocoo.org/docs/1.0/config/上查看更多信息

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

  1. 创建函数before_request

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

    app.before_request(before_request)
  3. 而已。

截至 2021 年 3 月更新:

建议使用烧瓶 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

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

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

还支持整个目录:

flask run --extra-files app/templates/

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

@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 的回答

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

$ pip install livereload

并运行代码

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)

此处使用extra_files参数或TEMPLATES_AUTO_RELOAD配置的所有答案都可以在服务器上重新加载它,但为了获得流畅的开发体验而不会损坏键盘的 F5 键,我会使用livereload

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

请参阅http://flask.pocoo.org/docs/1.0/quickstart/并使用FLASK_ENV=development

我有同样的麻烦。 解决方案非常简单。 而不是这个:

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

app.jinja_env.auto_reload = True
app.config["TEMPLATES_AUTO_RELOAD"] = True

上面的主要功能。 所以最终输出例如:

from flask import Flask, app,render_template

app= Flask(__name__)
app.jinja_env.auto_reload = True
app.config["TEMPLATES_AUTO_RELOAD"] = True

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

if __name__ == '__main__':    
    app.run(debug=True)
    

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

if __name__ == '__main__':之后添加app.config['TEMPLATES_AUTO_RELOAD'] = True对我不起作用!

有效的是在app = Flask(__name__)之后添加app.config['TEMPLATES_AUTO_RELOAD'] = True

请注意,我正在使用app.run(debug=True)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM