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
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.
I think Flask uses the directory template 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
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 templates folder.
If you must use a customized project directory structure (other than the accepted answer project structure),
we have the option 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...).
Within a sub-directory...
template_folder='templates/some_template'
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.
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.
Check that:
the template file has the right name
the template file is in a subdirectory called templates
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.)
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.
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.
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
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 :
the file does not exist or
the templates folder does not exist
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.
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)
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/'
)
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.
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.
I am using AWS to host my media files from my django app. I am following this tutorial, and when I use the following code,
from storages.backends.s3boto import S3BotoStorage
class MediaStorage(S3BotoStorage):
location = 'media'
MEDIA_URL = "https://%s/media/" % (AWS_S3_CUSTOM_DOMAIN)
DEFAULT_FILE_STORAGE = 'MediaStorage'
I get this error:
MediaStorage doesn't look like a module path
I have know idea why. Any thoughts?
You have to set the full module path for DEFAULT_FILE_STORAGE. See sample from documentation
DEFAULT_FILE_STORAGE
Default: 'django.core.files.storage.FileSystemStorage'
So put MediaStorage class in a storage.py module (path project/storage.py) and point DEFAULT_FILE_STORAGE='project.storage.MediaStorage'
I'm currently coding an image upload in a view and I want to compare it to the code the admin uses for uploading images. Is there code the admin generates the file forms from? Where can I find the python code to an admin image/file upload?
I'm using ubuntu 14, python 2.7 and django 1.9.
I have been searching around in here for the admin code for uploading files, but I cannot find it:
/usr/local/lib/python2.7/dist-packages/django/
This is my image upload code in my view I want to compare to the admin image upload code:
avatarFile=request.FILES["avatar_im"]
print(avatarFile)
for key, file in request.FILES.items():
path = file.name
path = "images/"+path
dest = open(path, 'w')
if file.multiple_chunks:
for a in file.chunks():
dest.write(a)
else:
dest.write(file.read())
dest.close()
I'm trying to understand how my admin uploads files to my
MEDIA_ROOT/images, and why my code uploads to my PROJECT_ROOT/images folder.
PROJECT_ROOT = os.path.normpath(os.path.dirname(__file__))
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'static_in_pro/media')
I think the code used for file uploading stays inside
django.core.files.storage.FileSystemStorage
and
django.core.files.move
If you want to upload files in the directory MEDIA_ROOT/images/ then just use:
import os
from django.conf import settings
...
...
path = os.path.join(settings.MEDIA_ROOT, 'images', file.name)
I want to open a html file i.e map.html which is saved in same directories where i saved this views.py and urls.py. (django based platform)
I wrote this sample code for views.py (to load map.html) but it is not working:
from django.template import Template, Context,RequestContext
from django.http import HttpResponse
import datetime
def router_map(request):
fp = open('./map.html')
t = Template(fp.read())
fp.close()
html = t.render(Context({'router_map'}))
return HttpResponse(html)
and my urls.py is:
from django.conf.urls.defaults import *
from umit.views import router_map
urlpatterns = patterns('',
(r'^index/$', router_map),
)
The problem is, I think, that you are using the path './map.html'. This is means that Python will try and find the current directory of the program, not the same directory as the view file is in.
Lets say the Django project is in the directory /home/foo/myproject. If you cd to that directory and run python manager.py runserver, the current directory inside the application (i.e. the directory .) will be /home/foo/myproject, which is not what you want.
The easiest way to fix this is to use the full path to the file in your call to open:
fp = open('/home/foo/myproject/myapp/views/map.html')
I'm running the 1.4.2 appengine SDK locally on a windows machine. I have an application running Django 0.96. The template rendering is using the django wrapper from
google.appengine.ext.webapp.template.render
to render templates. I often use a relative path to link my templates e.g
{% extends "../templates/base.html" %}
After upgrading to Django 1.2 the find_template method from
django.template.loader in the appengine's Django 1.2 lib folder is now raising a TemplateDoesNotExist when the relative paths are used
for loader in template_source_loaders:
try:
#raises TemplateDoesNotExist name='../templates/home.html' dirs=None
source, display_name = loader(name, dirs)
return (source, make_origin(display_name, loader, name, dirs))
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(name)
I've been stepping through the Django and AppEngine code for a while now but can't see any reason for this. Can anyone provide any more insight?
Thanks,
Richard
This problem bit me too when I converted from 0.96 to 1.2 Django templates. I was initially pushed to do so when SDK 1.4.2 started issuing the warning that I needed to pick a version, but when I looked into the much-needed improvements in the template language, I was eager to make the change.
And then everything broke. Like you, I used a lot of relative paths in my extends and include commands. It took a lot of debugging and digging, but I did figure out the cause of the problem and a pretty good solution.
The cause: in Django 1.2, the code that loads template files started using a command called safe_join to join path parts (you can see the code in google_appengine\lib\django_1_2\django\template\loaders\filesystem.py) . It won't allow relative paths to go above what it thinks of as the top-level directory. This is the same thing as a web server being configured to prevent you gaining access to the server's whole filesystem just by sticking some ..'s into your URL. The end result is that the
{% extends "../templates/base.html" %}
that used to be just fine breaks the rules and it isn't going to work.
The way that I fixed this in my application without completely restructuring how my templates are laid out is by implementing a custom TemplateLoader. Django's template rendering engine allows an application to have many different classes that know how to find templates in different ways. If you look in the directory that I gave above, you'll see that there are several provided, and they are all classes that inherit from BaseLoader. I provided my own that is custom-tailored to how my templates are laid out.
My project has a Rails-like lay-out:
app/
controllers/
home_controller.py
posts_controller.py
models/
...
views/
home/
index.html
about.html
posts/
show.html
new.html
shared/
base.html
post.html
Every template extends base.html and a couple include post.html, and they previously used relative paths to get to their location in base/. Ideally, I didn't even want to use the .. up-dir to get there, but it was required with 0.96. I created the following template loader to work with my scheme:
from django.conf import settings
from django.template import TemplateDoesNotExist
from django.template.loader import BaseLoader
from django.utils._os import safe_join
import os
class MvcTemplateLoader(BaseLoader):
"A custom template loader for the MVCEngine framework."
is_usable = True
__view_paths = None
def __init__(self, views_path):
self.views_path = views_path
# We only need to instantiate the view_paths class variable once.
if MvcTemplateLoader.__view_paths is None:
temp_paths = []
for each_path in os.listdir(views_path):
# We want to skip hidden directories, so avoid anything that starts with .
# This works on both Windows and *NIX, but could it fail for other OS's?
if not each_path.startswith('.'):
full_path = os.path.join(views_path, each_path)
if each_path == "shared":
# The shared directory is special. Since templates in many other directories will be
# inheriting from or including templates there, it should come second, right after the
# root views directory. For now, it will be first.
temp_paths.insert(0, full_path)
else:
temp_paths.append(full_path)
# The root views_path itself will always be first in order to give resolution precendence to templates
# that are specified with a parent directory. In other words, home/index.html will be immediately
# resolved with no ambiguity; whereas, index.html could resolve as bar/index.html rather than
# foo/index.html.
temp_paths.insert(0, views_path)
MvcTemplateLoader.__view_paths = temp_paths
def get_template_sources(self, template_name):
for template_dir in MvcTemplateLoader.__view_paths:
try:
yield safe_join(template_dir, template_name)
except UnicodeDecodeError:
# The template dir name was a bytestring that wasn't valid UTF-8.
raise
except ValueError:
# The joined path was located outside of this particular
# template_dir (it might be inside another one, so this isn't
# fatal).
pass
def load_template_source(self, template_name, template_dirs=None):
tried = []
for filepath in self.get_template_sources(template_name):
try:
file = open(filepath)
try:
return (file.read().decode(settings.FILE_CHARSET), filepath)
finally:
file.close()
except IOError:
tried.append(filepath)
error_msg = "Could not find %s in any of the views subdirectories." % template_name
raise TemplateDoesNotExist(error_msg)
load_template_source.is_usable = True
_loader = MvcTemplateLoader
And I caused my custom template loader to be included in the collection that Django tries by changing my application's main function to look like this:
def main():
from google.appengine.dist import use_library
use_library('django', '1.2')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.conf import settings
views_path = os.path.join(os.path.dirname(__file__), 'app','views')
settings.TEMPLATE_LOADERS = (('gaemvclib.mvctemplateloader.MvcTemplateLoader', views_path), 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader')
(and then all the rest of the stuff that normally goes into your main function).
So, I think that you should be able to modify the TemplateLoader code above to match how you have your template directories laid out, and it will give you a greater control over not only how you layout you templates hierarcy but also how you write your extends and include statement. You no longer use .. but rather just give the path of the template relative to whatever in your project is the equivalent of my views directory.
One reason you get the error message TemplateDoesNotExist: templates\AdminListstr.html
Doublecheck the slash you use between "templates" and your template name. I wasted a few hours, then checked the value being returned by os.path.join.
In summary you need to insure you are using "/" not the Windows "\". If you use the wrong slash, your code will work on (Windows) development but fail when deployed.
My diagnostic code printed this: look at the last slash
And the value returned by os.path.join is:/base/data/home/apps/s~myapp/1.356037954289984934/templates\LabListstr.html
Aye yi yi!