【问题标题】:Flask raises TemplateNotFound error even though template file exists即使模板文件存在,Flask 也会引发 TemplateNotFound 错误
【发布时间】:2014-06-13 04:26:42
【问题描述】:

我正在尝试渲染文件home.html。该文件存在于我的项目中,但是当我尝试渲染它时,我不断收到jinja2.exceptions.TemplateNotFound: home.html。为什么 Flask 找不到我的模板?

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('home.html')
/myproject
    app.py
    home.html

【问题讨论】:

    标签: python file templates flask


    【解决方案1】:

    您必须在正确的位置创建模板文件;在 python 模块旁边的 templates 子目录中(== 您创建 Flask 应用程序的模块)。

    错误提示templates/目录下没有home.html文件。确保您在与 python 模块相同的目录中创建了该目录,并且您确实在该子目录中放置了一个 home.html 文件。如果您的应用是一个包,则应在包创建模板文件夹。

    myproject/
        app.py
        templates/
            home.html
    
    myproject/
        mypackage/
            __init__.py
            templates/
                home.html
    

    或者,如果您将模板文件夹命名为 templates 以外的其他名称,并且不想将其重命名为默认值,您可以告诉 Flask 使用该其他目录。

    app = Flask(__name__, template_folder='template')  # still relative to module
    

    您可以通过将EXPLAIN_TEMPLATE_LOADING option 设置为True 来让Flask 解释它是如何尝试查找给定模板的。对于加载的每个模板,您都会在Flask app.logger 的级别INFO 中获得一份报告。

    这是搜索成功时的样子;在此示例中,foo/bar.html 模板扩展了 base.html 模板,因此有两个搜索:

    [2019-06-15 16:03:39,197] INFO in debughelpers: Locating template "foo/bar.html":
        1: trying loader of application "flaskpackagename"
           class: jinja2.loaders.FileSystemLoader
           encoding: 'utf-8'
           followlinks: False
           searchpath:
             - /.../project/flaskpackagename/templates
           -> found ('/.../project/flaskpackagename/templates/foo/bar.html')
    [2019-06-15 16:03:39,203] INFO in debughelpers: Locating template "base.html":
        1: trying loader of application "flaskpackagename"
           class: jinja2.loaders.FileSystemLoader
           encoding: 'utf-8'
           followlinks: False
           searchpath:
             - /.../project/flaskpackagename/templates
           -> found ('/.../project/flaskpackagename/templates/base.html')
    

    蓝图也可以register their own template directories,但如果您使用蓝图更容易将更大的项目拆分为逻辑单元,则不需要这样做。即使为每个蓝图使用额外的路径,也总是首先搜索主 Flask 应用程序模板目录。

    【讨论】:

    • 似乎我的本地烧瓶(在 Windows 上)可以在 ./Templates/index.html 中找到模板,但是当我部署到 heroku 时(认为它是相同的 Python,相同的库版本,包括相同的 Flask 版本;但 heroku 是Unix);并抛出TemplateNotFound 错误;在我重命名文件夹 git mv Templates/index.html templates/index.html 后,本地 (Windows) 和 heroku (Unix) 版本都可以使用
    • @TheRedPea 是的,因为 Windows 文件系统会折叠大小写,所以 Templates == templates。但是 Heroku 运行 Linux,文件系统区分大小写。
    【解决方案2】:

    我认为 Flask 默认使用目录templates。所以你的代码应该是这样的

    假设这是你的hello.py

    from flask import Flask,render_template
    
    app=Flask(__name__,template_folder='template')
    
    
    @app.route("/")
    def home():
        return render_template('home.html')
    
    @app.route("/about/")
    def about():
        return render_template('about.html')
    
    if __name__=="__main__":
        app.run(debug=True)
    

    你的工作空间结构像

    project/
        hello.py        
        template/
             home.html
             about.html    
        static/
               js/
                 main.js
               css/
                   main.css
    

    您还创建了两个名为 home.htmlabout.html 的 html 文件,并将这些文件放在 templates 文件夹中。

    【讨论】:

    • 这完全出乎意料,默认是一个名为模板的文件夹。为我修复了它,必须警惕无用的默认值。
    【解决方案3】:

    (请注意,上述为文件/项目结构提供的已接受答案是绝对正确的。)

    还有..

    除了正确设置项目文件结构外,我们还必须告诉flask在目录层次结构的适当级别中查找。

    例如..

        app = Flask(__name__, template_folder='../templates')
    
        app = Flask(__name__, template_folder='../templates', static_folder='../static')
    

    ../ 开始向后移动一个目录并从那里开始。

    ../../ 开始向后移动两个目录并从那里开始(等等......)。

    希望对你有帮助

    【讨论】:

      【解决方案4】:

      我不知道为什么,但我不得不改用以下文件夹结构。我把“模板”提高了一级。

      project/
          app/
              hello.py
              static/
                  main.css
          templates/
              home.html
          venv/
      

      这可能表明其他地方存在错误配置,但我无法弄清楚那是什么,并且这有效。

      【讨论】:

      • 你确定你有app = Flask(__name__)
      • 我也没有在app/ 中看到__init__.py 文件。
      【解决方案5】:

      如果您从已安装的包中运行代码,请确保模板文件存在于目录 <python root>/lib/site-packages/your-package/templates 中。


      一些细节:

      在我的例子中,我试图运行 flask_simple_uijinja 项目的示例,总是会说

      jinja2.exceptions.TemplateNotFound: form.html

      诀窍是示例程序将导入已安装的包flask_simple_ui。从该包内部使用的ninja 用作查找包路径的根目录,在我的情况下为...python/lib/site-packages/flask_simple_ui,而不是预期的os.getcwd()

      我倒霉的是,setup.py 有一个错误并且不会复制任何 html 文件,包括丢失的form.html。一旦我修复了setup.pyTemplateNotFound 的问题就消失了。

      我希望它对某人有所帮助。

      【讨论】:

        【解决方案6】:

        检查:

        1. 模板文件的名称正确
        2. 模板文件位于名为templates 的子目录中
        3. 您传递给render_template 的名称是相对于模板目录的(index.html 将直接位于模板目录中,auth/login.html 将位于模板目录中的 auth 目录下。)
        4. 您要么没有与您的应用同名的子目录,要么模板目录位于该子目录中。

        如果这不起作用,请打开调试 (app.debug = True),这可能有助于找出问题所在。

        【讨论】:

          【解决方案7】:

          我有同样的错误原来我做错的唯一一件事是命名我的'模板'文件夹,'模板'没有's'。 更改后它工作正常,不知道为什么它是一个东西,但它是。

          【讨论】:

            【解决方案8】:

            您需要将所有 .html 文件放在 python 模块旁边的 template 文件夹中。如果您在 html 文件中使用了任何图像,那么您需要将所有文件放在名为 static

            的文件夹中

            在以下结构中

            project/
                hello.py
                static/
                    image.jpg
                    style.css
                templates/
                    homepage.html
                virtual/
                    filename.json
            

            【讨论】:

              【解决方案9】:

              当使用 render_template() 函数时,它会尝试在名为 templates 的文件夹中搜索模板,并在以下情况下抛出错误 jinja2.exceptions.TemplateNotFound:

              1. 文件不存在或
              2. 模板文件夹不存在

              在python文件所在的同一目录下创建一个名为templates的文件夹,并将创建的html文件放在templates文件夹中。

              【讨论】:

                【解决方案10】:

                另一种选择是设置root_path,它可以解决模板和静态文件夹的问题。

                root_path = Path(sys.executable).parent if getattr(sys, 'frozen', False) else Path(__file__).parent
                app = Flask(__name__.split('.')[0], root_path=root_path)
                

                如果你直接通过Jinja2渲染模板,那么你写:

                ENV = jinja2.Environment(loader=jinja2.FileSystemLoader(str(root_path / 'templates')))
                template = ENV.get_template(your_template_name)
                

                【讨论】:

                  【解决方案11】:

                  我的问题是我在home.html 中引用的文件是.j2 而不是.html,当我将它改回来时,jinja 可以读取它。

                  愚蠢的错误,但它可能对某人有所帮助。

                  【讨论】:

                    【解决方案12】:

                    我自己想出的另一种解释 创建 Flask 应用程序时,查找templates 的文件夹是根据您提供给 Flask 构造函数的名称的应用程序文件夹:

                    app = Flask(__name__)
                    

                    这里的__name__ 是运行应用程序的模块的名称。因此,相应的文件夹将成为文件夹搜索的根目录。

                    projects/
                        yourproject/
                            app/
                                templates/
                    

                    因此,如果您提供一些随机名称,则搜索的根文件夹将是当前文件夹。

                    【讨论】:

                      【解决方案13】:

                      Flask 会自动在 templates 目录 中查找 HTML 模板,这意味着您需要确保实际保存所有 HTML 文件的文件夹名为 templates

                      结构:

                      Application/
                            run.py
                            templates/
                              index.html
                      

                      【讨论】:

                        猜你喜欢
                        • 2021-05-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多