Flask 抛出 TemplateNotFound 错误即使模板文件存在

238 投票
18 回答
349489 浏览
提问于 2025-04-18 04:29

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

18 个回答

4

如果你是从一个已安装的包里运行你的代码,记得确保模板文件在这个目录下:<python root>/lib/site-packages/your-package/templates


一些细节:

在我的情况下,我试图运行项目flask_simple_ui的示例代码,结果jinja总是提示我

jinja2.exceptions.TemplateNotFound: form.html

问题在于,示例程序会导入已安装的包flask_simple_ui。而在这个包内部使用的jinja,它查找模板文件的根目录是这个包的路径,也就是...python/lib/site-packages/flask_simple_ui,而不是大家通常期待的os.getcwd()

不幸的是,setup.py有个bug,没有复制任何html文件,包括缺失的form.html。一旦我修复了setup.pyTemplateNotFound的问题就消失了。

希望这能帮助到某些人。

7

我不知道为什么,但我不得不使用下面这种文件夹结构。我把“templates”文件夹放到上一级。

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

这可能说明其他地方的设置有问题,但我搞不清楚是什么问题,不过这样做是有效的。

24

如果你需要使用一个自定义的项目目录结构(也就是和大家常用的项目结构不一样),我们可以告诉Flask去合适的目录层级找文件。

比如说……

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

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

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

在一个子目录中……

template_folder='templates/some_template'
40

我觉得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.html,并把这两个文件放在templates文件夹里。

427

你需要把模板文件放在正确的位置,也就是在和你的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选项设置为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')

蓝图(Blueprints)也可以注册自己的模板目录,但如果你使用蓝图来更好地将一个大项目拆分成逻辑单元,这并不是必须的。即使使用蓝图的额外路径,Flask应用的主模板目录总是会被优先搜索。

撰写回答