提问人:Srdan Ristic 提问时间:4/28/2014 最后编辑:Martijn PietersSrdan Ristic 更新时间:7/30/2023 访问量:328788
即使模板文件存在,Flask 也会引发 TemplateNotFound 错误
Flask raises TemplateNotFound error even though template file exists
问:
我正在尝试渲染文件。该文件存在于我的项目中,但是当我尝试渲染它时,我不断得到它。为什么 Flask 找不到我的模板?home.html
jinja2.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 模块旁边的子目录中(== 用于创建 Flask 应用的模块)。templates
该错误表示目录中没有文件。确保您在与 python 模块相同的目录中创建了该目录,并且您确实在该子目录中放置了一个文件。如果应用是包,则应在包内创建 templates 文件夹。home.html
templates/
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
的级别。True
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 应用程序模板目录始终首先搜索,即使对每个蓝图使用其他路径也是如此。
评论
./Templates/index.html
TemplateNotFound
git mv Templates/index.html templates/index.html
Templates
templates
检查:
- 模板文件具有正确的名称
- 模板文件位于名为
templates
- 您传递到的名称是相对于模板目录的(将直接位于 templates 目录中,将位于 templates 目录中的 auth 目录下。
render_template
index.html
auth/login.html
- 你要么没有与应用同名的子目录,要么 templates 目录位于该子目录中。
如果这不起作用,请打开调试 (),这可能有助于找出问题所在。app.debug = True
我不知道为什么,但我不得不改用以下文件夹结构。我把“模板”提高了一级。
project/
app/
hello.py
static/
main.css
templates/
home.html
venv/
这可能表明其他地方的配置错误,但我无法弄清楚那是什么,这起作用了。
评论
app = Flask(__name__)
__init__.py
app/
您需要将所有文件放在 python 模块旁边的模板文件夹中。如果您在html文件中使用了任何图像,则需要将所有文件放在名为static的文件夹中.html
在以下结构中
project/
hello.py
static/
image.jpg
style.css
templates/
homepage.html
virtual/
filename.json
我遇到了同样的错误,事实证明我唯一做错的事情是将我的“模板”文件夹命名为“模板”而没有“s”。 更改后它工作正常,不知道为什么它是一回事,但它是。
我认为 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.html
about.html
templates
评论
当使用 render_template() 函数时,它会尝试在名为 templates 的文件夹中搜索模板,并在以下情况下抛出错误 jinja2.exceptions.TemplateNotFound:
- 文件不存在或
- templates 文件夹不存在
在 python 文件所在的同一目录中创建一个名称为 templates 的文件夹,并将创建的 html 文件放在 templates 文件夹中。
如果必须使用自定义项目目录结构(接受的答案项目结构除外), 我们可以选择告诉 Flask 查看目录层次结构的相应级别。
例如。。
app = Flask(__name__, template_folder='../templates')
app = Flask(__name__, template_folder='../templates', static_folder='../static')
“从开始”向后移动一个目录并从那里开始。../
“从开始”向后移动两个目录,然后从那里开始(依此类推......../../
在子目录中...
template_folder='templates/some_template'
另一种替代方法是设置 这可以解决模板和静态文件夹的问题。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)
如果从已安装的包运行代码,请确保模板文件存在于目录 中。<python root>/lib/site-packages/your-package/templates
一些细节:
就我而言,我试图运行项目flask_simple_ui示例,并且总是会说jinja
jinja2.exceptions.TemplateNotFound:表单.html
诀窍是示例程序将导入已安装的包。从该包内部使用是用作查找包路径的根目录,在我的情况下,而不是人们所期望的那样。flask_simple_ui
ninja
...python/lib/site-packages/flask_simple_ui
os.getcwd()
不幸的是,有一个错误并且没有复制任何 html 文件,包括丢失的 .一旦我修复了,TemplateNotFound的问题就消失了。setup.py
form.html
setup.py
我希望它对某人有所帮助。
我的问题是我从我的内部引用的文件是 a 而不是 ,当我把它改回来时,jinja 可以读取它。home.html
.j2
.html
愚蠢的错误,但它可能会帮助某人。
我自己想出的另一个解释
创建 Flask 应用程序时,根据你提供给 Flask 构造函数的名称,查找的文件夹是应用程序的文件夹:templates
app = Flask(__name__)
这里是运行应用程序的模块的名称。因此,相应的文件夹将成为文件夹搜索的根文件夹。__name__
projects/
yourproject/
app/
templates/
因此,如果您提供一些随机名称,则搜索的根文件夹将是当前文件夹。
经过大量工作,我只从这篇文章中得到了解决方案,链接到解决方案帖子
为参数添加完整路径template_folder
app = Flask(__name__,
template_folder='/home/project/templates/'
)
我的是一个愚蠢的错误。我输入了通行证,如下所示:templates
return render_template('./templates/index.html')
但是,您只需要提供相对于目录的传递,即:templates
return render_template('./index.html')
如果有人第一次运行您的 Python 代码,并且您在顶级应用程序 = Flask(__name__, template_folder='')
的同一目录中创建 HTML 文件和 Python 文件,这将起作用
我的解决方案是针对谁设置了烧瓶应用程序名称
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
我最近遇到了同样的问题。 我想使用 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”标志在这里有所帮助!
希望这将有助于节省调试时间:-)
无需更改,只需将文件放入模板文件夹中即可。index.html
下一个:什么是非演绎上下文?
评论