Reputation: 3503
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
Upvotes: 252
Views: 383423
Reputation: 931
side answer, in my case error was string 'main'
app = Flask('__main__', template_folder='templates')
this some how 'main' make the config for different app so thats why the original app not able to find templates when change back to __name__
it worked
app = Flask(__name__, template_folder='templates')
[as documentation says about name][1]
The first argument is the name of the application’s module or package. If you are using a single module (as in this example), you should use name because depending on if it’s started as application or imported as module the name will be different ('main' versus the actual import name).
Upvotes: 0
Reputation: 619
I think Flask uses the directory templates
by default. So your code should be like this
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
templates/
home.html
about.html
static/
js/
main.js
css/
main.css
Also, you have to create two html files with name of home.html
and about.html
and put those files in templates
folder.
Upvotes: 44
Reputation: 602
We simply need to look in the appropriate level of the project directory hierarchy. The takeaway is to understand your file structure and organizational layout.
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...).
or Within a sub-directory... (working into the directory tree)
template_folder='templates/some_template/nested_directory/nested_file.py'
Upvotes: 25
Reputation: 636
No change is needed just put index.html
file inside the templates folder.
Upvotes: 3
Reputation: 597
I had the same issue recently. I wanted to "--onefile exe" my Python scripts with pyinstaller, but the jinja2 template used was not available: "jinja2.exceptions.TemplateNotFound"
But first here is what helped:
pyinstaller --clean --onefile --windowed --add-data "..\templates*;templates." --splash ..\img\splash2.png ..\main.py
And the code where you load the jinja template itself:
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)
Now to the whys.
First: If you use "--onefile" flag, pyinstaller will create a single .exe file. When you run it, the operating system will extract the files to a temporary MEIPASS folder under your personal account. That's why we need to differentiate between "if getattr(sys, 'frozen', False):" and running the script the "normal way" (as sown in the code snippet).
Second: Jinja normally ignores *.txt files, therefore I have also seen some suggestions to create a fake python file to fool the pyInstaller. There is no need to do this, just set the flag "--add-data origin;destination" (here I add all the files in the template folder also to the template folder but in the destination directory). You will need to use ":" instead of ";" as delimiter for unix systems.
Thirdly, I ran into a bug where the templates wouldn't be added even though I set the "--add-data" flag. An additional "--clean" flag helped here!
Hopefully it will help save debugging time :-)
Upvotes: -1
Reputation: 133
My solution is for who has set the flask app Name
from flask import Flask, render_template
app = Flask('MATH') # <---- the name should be different from project folder name. For example uppercase
@app.route('/')
It's very important to put flask instance name different from project directory name. For example 'math1' or 'Math' or 'MATH'
project tree:
/math/
app.py
templates/
hello.html
Upvotes: 2
Reputation: 653
if anyone running first time your python code and if u create a html file and python file in same directory of top level
app = Flask(__name__, template_folder='')
this will work
Upvotes: 4
Reputation: 113
Mine was a silly mistake. I put templates
in the pass, like so:
return render_template('./templates/index.html')
HOWEVER, you simply just have to give the pass relative to the templates
directory, that is:
return render_template('./index.html')
Upvotes: 0
Reputation: 1210
After lots of work around, I got solution from this post only, Link to the solution post
Add full path to template_folder parameter
app = Flask(__name__,
template_folder='/home/project/templates/'
)
Upvotes: 2
Reputation: 179
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 :
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.
Upvotes: 2
Reputation: 1121864
You must create your template files in the correct location; in the templates
subdirectory next to the python module (== the module where you create your Flask app).
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.
Upvotes: 440
Reputation: 815
Another explanation I've figured out for myself
When you create the Flask application, the folder where templates
is looked for is the folder of the application according to name you've provided to Flask constructor:
app = Flask(__name__)
The __name__
here is the name of the module where application is running. So the appropriate folder will become the root one for folders search.
projects/
yourproject/
app/
templates/
So if you provide instead some random name the root folder for the search will be current folder.
Upvotes: -2
Reputation: 2076
My problem was that the file I was referencing from inside my home.html
was a .j2
instead of a .html
, and when I changed it back jinja could read it.
Stupid error but it might help someone.
Upvotes: 0
Reputation: 695
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.
Upvotes: 4
Reputation: 1805
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)
Upvotes: 1
Reputation: 41
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.
Upvotes: 3
Reputation: 1388
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.
Upvotes: 7
Reputation: 5355
Check that:
templates
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.)If that doesn't work, turn on debugging (app.debug = True
) which might help figure out what's wrong.
Upvotes: 3
Reputation: 553
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
Upvotes: 2