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

Flask raises TemplateNotFound error even though template file exists

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

1
2
3
4
5
6
7
from flask import Flask, render_template

app = Flask(__name__)

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

您必须在正确的位置创建模板文件。在python模块旁边的templates子目录中。

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

1
2
3
4
myproject/
    app.py
    templates/
        home.html
1
2
3
4
5
myproject/
    mypackage/
        __init__.py
        templates/
            home.html

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

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

您可以通过将EXPLAIN_TEMPLATE_LOADING选项设置为True来要求Flask解释其如何尝试查找给定的模板。对于每个加载的模板,您将获得一个报告,记录到级别INFO的Flask app.logger中。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[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应用程序主模板目录。


我认为Flask默认使用目录模板。所以你的代码应该是
假设这是你的hello.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)

你的工作空间结构就像

1
2
3
4
5
6
7
8
9
10
project/
    hello.py        
    template/
         home.html
         about.html    
    static/
           js/
             main.js
           css/
               main.css

您还创建了两个HTML文件,名称分别为home.html和about.html,并将它们放在模板文件夹中。


在遵循该主题和其他主题为相同问题的解决方案而没有成功之后,我找到了适用于当前项目的可行解决方案。
(请注意,上面为文件/项目结构提供的已接受答案在大多数情况下都可以使用,并且绝对正确,我只是在说明适合我的方法。)

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

对于/static/style.css同样如此
发现.css文件未正确链接到.html文件后...

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

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

我希望这有帮助


我不知道为什么,但是我不得不使用以下文件夹结构。我将"模板"提高了一层。

1
2
3
4
5
6
7
8
project/
    app/
        hello.py
        static/
            main.css
    templates/
        home.html
    venv/

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


检查:

  • 模板文件具有正确的名称
  • 模板文件位于名为templates的子目录中
  • 您传递给render_template的名称是相对于模板目录的(index.html将直接位于模板目录中,auth/login.html将位于模板目录中的auth目录下。)
  • 您可能没有与您的应用同名的子目录,或者模板目录位于该子目录中。
  • 如果这不起作用,请打开调试(app.debug = True),这可能有助于找出问题所在。


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


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

    在以下结构中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    project/
        hello.py
        static/
            image.jpg
            style.css
        templates/
            homepage.html
        virtual/
            filename.json

    如果从已安装的程序包运行代码,请确保模板文件位于目录/lib/site-packages/your-package/templates中。

    一些细节:

    在我的情况下,我试图运行项目flask_simple_ui的示例,并且jinja总是会说

    jinja2.exceptions.TemplateNotFound: form.html

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

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

    希望对您有所帮助。


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

    1
    2
    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渲染模板,则可以编写:

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

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

  • html文件不存在或
  • 当模板文件夹不存在时
  • 解决此问题的方法:在python文件所在的目录中创建一个带有名称模板的文件夹,并将创建的html文件放置在templates文件夹中。