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

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

我正在尝试渲染文件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

I am trying to render the file home.html. The file exists in my project, but I keep getting jinja2.exceptions.TemplateNotFound: home.html when I try to render it. Why can’t Flask find my template?

from flask import Flask, render_template

app = Flask(__name__)

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

回答 0

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

该错误表明目录中没有home.html文件templates/。确保在与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选项True。对于每个加载的模板,您将获得一个报告记录到Flaskapp.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')

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

You must create your template files in the correct location; in the templates subdirectory next to your python module.

The error indicates that there is no home.html file in the templates/ directory. Make sure you created that directory in the same directory as your python module, and that you did in fact put a home.html file in that subdirectory. If your app is a package, the templates folder should be created inside the package.

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

Alternatively, if you named your templates folder something other than templates and don’t want to rename it to the default, you can tell Flask to use that other directory.

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

You can ask Flask to explain how it tried to find a given template, by setting the EXPLAIN_TEMPLATE_LOADING option to True. For every template loaded, you’ll get a report logged to the Flask app.logger, at level INFO.

This is what it looks like when a search is successful; in this example the foo/bar.html template extends the base.html template, so there are two searches:

[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')

Blueprints can register their own template directories too, but this is not a requirement if you are using blueprints to make it easier to split a larger project across logical units. The main Flask app template directory is always searched first even when using additional paths per blueprint.


回答 1

我认为Flask默认使用目录模板。因此,您的代码应该假设这是您的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.html和about.html,并将它们放在模板文件夹中。

I think Flask uses the directory templates by default. So your code should be suppose this is your 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)

And you work space structure like

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

also you have create two html files with name of home.html and about.html and put those files in template folder.


回答 2

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

也..

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

例如..

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

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

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

希望这可以帮助

(Please note that the above accepted Answer provided for file/project structure is absolutely correct.)

Also..

In addition to properly setting up the project file structure, we have to tell flask to look in the appropriate level of the directory hierarchy.

for example..

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

Starting with ../ moves one directory backwards and starts there.

Starting with ../../ moves two directories backwards and starts there (and so on…).

Hope this helps


回答 3

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

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

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

I don’t know why, but I had to use the following folder structure instead. I put “templates” one level up.

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

This probably indicates a misconfiguration elsewhere, but I couldn’t figure out what that was and this worked.


回答 4

检查:

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

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

Check that:

  1. the template file has the right name
  2. the template file is in a subdirectory called templates
  3. the name you pass to render_template is relative to the template directory (index.html would be directly in the templates directory, auth/login.html would be under the auth directory in the templates directory.)
  4. you either do not have a subdirectory with the same name as your app, or the templates directory is inside that subdir.

If that doesn’t work, turn on debugging (app.debug = True) which might help figure out what’s wrong.


回答 5

如果从已安装的程序包运行代码,请确保目录中存在模板文件<python root>/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文件,包括missing form.html。一旦修复setup.pyTemplateNotFound的问题就消失了。

希望对您有所帮助。

If you run your code from an installed package, make sure template files are present in directory <python root>/lib/site-packages/your-package/templates.


Some details:

In my case I was trying to run examples of project flask_simple_ui and jinja would always say

jinja2.exceptions.TemplateNotFound: form.html

The trick was that sample program would import installed package flask_simple_ui. And ninja being used from inside that package is using as root directory for lookup the package path, in my case ...python/lib/site-packages/flask_simple_ui, instead of os.getcwd() as one would expect.

To my bad luck, setup.py has a bug and doesn’t copy any html files, including the missing form.html. Once I fixed setup.py, the problem with TemplateNotFound vanished.

I hope it helps someone.


回答 6

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

I had the same error turns out the only thing i did wrong was to name my ‘templates’ folder,’template’ without ‘s’. After changing that it worked fine,dont know why its a thing but it is.


回答 7

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

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

解决问题:

在python文件所在的目录中创建一个带有名称模板的文件夹,并将创建的html文件放置在模板文件夹中。

When render_template() function is used it tries to search for template in the folder called templates and it throws error jinja2.exceptions.TemplateNotFound when :

  1. the html file do not exist or
  2. when templates folder do not exist

To solve the problem :

create a folder with name templates in the same directory where the python file is located and place the html file created in the templates folder.


回答 8

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

在以下结构中

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

You need to put all you .html files in the template folder next to your python module. And if there are any images that you are using in your html files then you need put all your files in the folder named static

In the following Structure

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

回答 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)

Another alternative is to set the root_path which fixes the problem both for templates and static folders.

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

If you render templates directly via Jinja2, then you write:

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