【问题标题】:Reload Flask app when template file changes模板文件更改时重新加载 Flask 应用程序
【发布时间】:2012-03-19 12:03:30
【问题描述】:

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

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

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

那么,有没有办法将 Flask 监控文件放在 templates 目录中,还是需要深入到框架的源代码中?

编辑:我使用的是 Ubuntu 10.10。真的没有在任何其他平台上尝试过。


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

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

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

总而言之,这种现象的根源似乎位于 Jinja 和 Flask 或 Werkzeug 之间的某个地方。我想这可能需要为其中任何一个项目访问错误跟踪器 :) 同时,我接受了 jd. 的答案,因为这是我实际使用的解决方案 - 它就像一个魅力.

【问题讨论】:

  • 确保应用程序配置为 DEBUG=True,参见the docs

标签: python flask jinja2


【解决方案1】:

我也遇到了同样的问题。解决方案非常简单。而不是这个:

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)
    

【讨论】:

    【解决方案2】:

    2021 年 3 月更新:

    建议使用flask CLI 而非 app.run() 来运行开发服务器,因此如果我们想使用 CLI,则无法使用已接受的解决方案。

    在 Flask 1.1 或更高版本中,环境变量 FLASK_RUN_EXTRA_FILES 或选项 --extra-files 实际上与接受的答案相同。另见this github issue

    示例用法:

    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/
    

    【讨论】:

    • 小更新。指向“flask CLI”的链接需要更新到当前版本。 flask.palletsprojects.com/en/1.1.x/cli 否则谢谢:)
    • 我更新了链接并添加了整个目录也可以“观看”,我希望这是一个可以接受的编辑。
    【解决方案3】:

    为了在服务器和浏览器中重新加载应用程序,我使用了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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 这对我不起作用。它只是加载旧模板而没有新的更改
      • 使用 ``` app.config['TEMPLATE_AUTO_RELOAD'] = 'true' ``` 然后当你按下 crtl + f5 时它应该可以工作了。
      【解决方案5】:

      根据我的经验,模板甚至不需要重新启动应用程序即可刷新,因为每次调用 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 文档中提到了它。
      • 如果有人遇到No such file or directory 的错误,请尝试使用相对路径:extra_dirs = ['./directory/to/watch',]
      • 如果您也对path 是什么感到困惑,那就是os.path。觉得值得一提
      • 更改静态文件后自动重新加载见this
      • 知道如何在命令行运行flask run 时指定额外文件吗?
      【解决方案6】:

      对我来说效果很好:

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

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          实际上对我来说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 步并不是必须的,对我来说效果很好。
          【解决方案9】:

          你可以使用

          TEMPLATES_AUTO_RELOAD = True
          

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

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

          【讨论】:

          • 这个解决方案是传统的,有文档支持,简单易懂,易于实施。应该接受!
          • 我试过这个答案,但只能工作一次,再刷新一次就不行了
          • 只是给其他人的说明:我做了app.config['TEMPLATES_AUTO_RELOAD'] = True,并且出于某种原因,希望在模板更改时看到服务器自动重启,就像在调试模式下一样。它不会重新启动,但会更新它呈现的模板。
          • 为什么这不适用于 0.12?或其他一些会阻止它正确设置的设置?
          • @Federer 它似乎不像以前那样工作了......以前,它会检测到模板目录和子目录中的更改,它会重新加载服务器...... . 这是 0.12 中的新变化吗?
          【解决方案10】:

          当您使用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.0.2 上为我工作,但我没有主机参数。
          • 是的@EnricoBorba,你可能不需要它。我通常使用它,因为我在本地使用 docker 进行调试,有时需要从另一个容器访问应用程序。 Some Reference
          • @silgon 是的,我明白了。我主要只是添加评论以明确在全新安装 Flask 版本 1.0.2 上的工作原理
          【解决方案11】:

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

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

          【讨论】:

            【解决方案12】:

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

            【讨论】:

              猜你喜欢
              • 2017-04-25
              • 2014-06-17
              • 2013-04-27
              • 2016-08-10
              • 2023-02-11
              • 2019-02-11
              • 1970-01-01
              相关资源
              最近更新 更多