即使模板文件存在,Flask 也会引发 TemplateNotFound 错误

Flask raises TemplateNotFound error even though template file exists

提问人:Srdan Ristic 提问时间:4/28/2014 最后编辑:Martijn PietersSrdan Ristic 更新时间:7/30/2023 访问量:328788

问:

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

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('home.html')
/myproject
    app.py
    home.html
python 文件 模板 烧瓶

评论


答:

416赞 Martijn Pieters 4/28/2014 #1

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

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

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

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

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

您可以要求 Flask 解释它如何尝试查找给定模板,方法是将 EXPLAIN_TEMPLATE_LOADING 选项设置为 。对于加载的每个模板,你将获得一个报告,记录到 Flask app.logger 的级别。TrueINFO

这就是搜索成功时的样子;在此示例中,模板扩展了模板,因此有两个搜索:foo/bar.htmlbase.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')

蓝图也可以注册自己的模板目录,但如果使用蓝图可以更轻松地跨逻辑单元拆分较大的项目,则不需要这样做。主 Flask 应用程序模板目录始终首先搜索,即使对每个蓝图使用其他路径也是如此。

评论

3赞 Nate Anderson 10/24/2019
似乎我的本地 Flask(在 Windows 上)可以在里面找到模板,但是当我部署到 heroku 时(以为它是相同的 Python、相同的库版本,包括相同的 Flask 版本;但 heroku 是 Unix);并抛出错误;重命名文件夹后,本地 (Windows) 和 heroku (Unix) 版本都可以工作./Templates/index.htmlTemplateNotFoundgit mv Templates/index.html templates/index.html
1赞 Martijn Pieters 10/24/2019
@TheRedPea是的,因为 Windows 文件系统折叠大小写,所以 == .但 Heroku 运行的是 Linux,文件系统区分大小写。Templatestemplates
3赞 Eric 4/28/2014 #2

检查:

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

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

7赞 François Breton 1/25/2017 #3

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

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

这可能表明其他地方的配置错误,但我无法弄清楚那是什么,这起作用了。

评论

0赞 Nikhil CSB 11/30/2020
你确定你有?app = Flask(__name__)
0赞 Martijn Pieters 1/19/2021
我也没有看到里面的文件。__init__.pyapp/
0赞 ishaj 6/11/2023
非常感谢!它像魔术一样工作。
2赞 Madhusudan chowdary 6/25/2017 #4

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

在以下结构中

project/
    hello.py
    static/
        image.jpg
        style.css
    templates/
        homepage.html
    virtual/
        filename.json
3赞 Shubham Khaire 2/5/2019 #5

我遇到了同样的错误,事实证明我唯一做错的事情是将我的“模板”文件夹命名为“模板”而没有“s”。 更改后它工作正常,不知道为什么它是一回事,但它是。

38赞 Akshay Karande 3/15/2019 #6

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

假设这是你的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

此外,您还创建了两个名为 和 的 HTML 文件,并将这些文件放在文件夹中。home.htmlabout.htmltemplates

评论

0赞 10/30/2021
这完全出乎意料,因为默认值是一个名为 templates 的文件夹。为我修复了它,将不得不警惕无用的默认值。
5赞 Amarnath Reddy Surapureddy 8/31/2022
文件夹名称是“templates”而不是“template”。
2赞 Vader 5/24/2019 #7

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

  1. 文件不存在或
  2. templates 文件夹不存在

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

23赞 None 6/1/2019 #8

如果必须使用自定义项目目录结构(接受的答案项目结构除外), 我们可以选择告诉 Flask 查看目录层次结构的相应级别。

例如。。

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

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

“从开始”向后移动两个目录,然后从那里开始(依此类推......../../

在子目录中...

template_folder='templates/some_template'
1赞 Max 6/14/2019 #9

另一种替代方法是设置 这可以解决模板和静态文件夹的问题。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)
4赞 yozniak 11/10/2019 #10

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


一些细节:

就我而言,我试图运行项目flask_simple_ui示例,并且总是会说jinja

jinja2.exceptions.TemplateNotFound:表单.html

诀窍是示例程序将导入已安装的包。从该包内部使用是用作查找包路径的根目录,在我的情况下,而不是人们所期望的那样。flask_simple_uininja...python/lib/site-packages/flask_simple_uios.getcwd()

不幸的是,有一个错误并且没有复制任何 html 文件,包括丢失的 .一旦我修复了,TemplateNotFound的问题就消失了。setup.pyform.htmlsetup.py

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

0赞 half of a glazier 11/5/2020 #11

我的问题是我从我的内部引用的文件是 a 而不是 ,当我把它改回来时,jinja 可以读取它。home.html.j2.html

愚蠢的错误,但它可能会帮助某人。

-2赞 Ralfeus 2/9/2021 #12

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

app = Flask(__name__)

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

projects/
    yourproject/
        app/
            templates/

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

1赞 Kiran 9/16/2022 #13

经过大量工作,我只从这篇文章中得到了解决方案,链接到解决方案帖子

为参数添加完整路径template_folder

app = Flask(__name__,
        template_folder='/home/project/templates/'
        )
0赞 heschmat 2/27/2023 #14

我的是一个愚蠢的错误。我输入了通行证,如下所示:templates

    return render_template('./templates/index.html')

但是,您只需要提供相对于目录的传递,即:templates

    return render_template('./index.html')
3赞 btm me 3/15/2023 #15

如果有人第一次运行您的 Python 代码,并且您在顶级应用程序 = Flask(__name__, template_folder='') 的同一目录中创建 HTML 文件和 Python 文件,这将起作用

1赞 Leila Nikonova 3/23/2023 #16

我的解决方案是针对谁设置了烧瓶应用程序名称

from flask import Flask, render_template

app = Flask('MATH') # <---- the name should be different from project folder name. For example uppercase

@app.route('/')

将 flask 实例名称与项目目录名称不同非常重要。例如,“math1”或“Math”或“MATH”

项目树:

/math/
  app.py
  templates/
    hello.html
0赞 Alexander Khomenko 7/8/2023 #17

我最近遇到了同样的问题。 我想使用 pyinstaller “--onefile exe” 我的 Python 脚本,但使用的 jinja2 模板不可用:“jinja2.exceptions.TemplateNotFound"

但首先这里是有帮助的:
pyinstaller --clean --onefile --windowed --add-data “..\模板*;模板。--溅。。\img\splash2.png ..\main.py

以及加载 jinja 模板本身的代码:

template_loader = ''
if getattr(sys, 'frozen', False):
    # for the case of running in pyInstaller's exe
    bundle_dir = sys._MEIPASS
    logging.info(bundle_dir)
    template_loader = jinja2.FileSystemLoader(
        path.join(bundle_dir, 'templates'))
else:
    # for running locally
    template_loader = jinja2.FileSystemLoader(searchpath="./templates")

template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('template_configuration_file.txt')
filled_template = template.render(columns=columns)

with open(output_path, "w") as fh:
    fh.write(filled_template)

现在来谈谈为什么。

首先:如果使用“--onefile”标志,pyinstaller 将创建一个 .exe 文件。当您运行它时,操作系统会将文件解压缩到您个人帐户下的临时 MEIPASS 文件夹中。这就是为什么我们需要区分“if getattr(sys, 'frozen', False):”和以“正常方式”运行脚本(如代码片段中播种的那样)。

第二:Jinja 通常会忽略 *.txt 文件,因此我也看到了一些创建假 python 文件来欺骗 pyInstaller 的建议。没有必要这样做,只需设置标志“--add-data origin;destination“(在这里,我将模板文件夹中的所有文件也添加到模板文件夹中,但在目标目录中)。您需要使用 “:” 而不是 “;” 作为 unix 系统的分隔符。

第三,我遇到了一个错误,即使我设置了“--add-data”标志,也不会添加模板。一个额外的“--clean”标志在这里有所帮助!

希望这将有助于节省调试时间:-)

0赞 MD Gazuruddin 7/30/2023 #18

pycharm screenshot

无需更改,只需将文件放入模板文件夹中即可。index.html