I am a beginner in the Django framework. I created my project created my app and test it, it work fine till I decided to add a template. I don't know where the error is coming from because I follow what Django docs say by creating folder name templates in your app folder creating a folder with your app name and lastly creating the HTML file in the folder.
NOTE: other routes are working fine except the template
Please view the screenshot of my file structure and error below.
File Structure
ERROR
TemplateDoesNotExist at /blog/
Blog/index
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/
Django Version: 4.0.1
Exception Type: TemplateDoesNotExist
Exception Value:
Blog/index
Exception Location: C:\Python39\lib\site-packages\django\template\loader.py, line 19, in get_template
Python Executable: C:\Python39\python.exe
Python Version: 3.9.4
Python Path:
['C:\\Users\\Maxwell\\Desktop\\Django\\WebApp',
'C:\\Python39\\python39.zip',
'C:\\Python39\\DLLs',
'C:\\Python39\\lib',
'C:\\Python39',
'C:\\Users\\Maxwell\\AppData\\Roaming\\Python\\Python39\\site-packages',
'C:\\Python39\\lib\\site-packages',
'C:\\Python39\\lib\\site-packages\\win32',
'C:\\Python39\\lib\\site-packages\\win32\\lib',
'C:\\Python39\\lib\\site-packages\\Pythonwin']
Server time: Sun, 23 Jan 2022 12:04:18 +0000
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: C:\Users\Maxwell\Desktop\Django\WebApp\Blog\templates\ Blog\index (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Python39\lib\site-packages\django\contrib\admin\templates\ Blog\index (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Python39\lib\site-packages\django\contrib\auth\templates\ Blog\index (Source does not exist)
App/views.py
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def index(request,name):
return HttpResponse(f'Hello {name}')
def html(request):
return render(request,' Blog/index.html')
It seems that you render the template with Blog/index, but you need to specify the entire file name, so Blog/index.html and without a leading (or trailing) space:
def html(request):
return render(request, 'Blog/index.html')
if #Willem van Onsem answer didn't work
create a templates folder in the main directory 'in the same level as WebApp'
then inside it create folders for each app
in your settings.py you will find TEMPLATES option
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR,'templates')],#add this line
...
]
and when you want to use a template
return render(request,"template_folder/template_name.html")
I faced this situation too, and went through most of the answers here talking about the path, and editing the 'templates' function in settings.py.
In the end, it was because I forgot to add my app to the installed apps section in the settings.py file. I saw this in the docs at https://docs.djangoproject.com/en/4.0/intro/tutorial03/#write-views-that-actually-do-something
Related
I'm new to Django, trying my hand at creating a web app based on the self learn tutorial. i have created a app with name "travello" and project name is "travellproject", in the views i'am trying to render a html page.
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def homepage(request):
return render(request,'homepage.html')
i have created the "templates" directory under travellproj (please refer the directory structure below) also defined DIRS of template variable as below and urls.py as below.
"DIRS": [os.path.join(BASE_DIR,'templates')],
urlpatterns = [
path("",views.homepage),
path("admin/", admin.site.urls),
]
But I'm receiving a TemplateDoesNotExist error, please help.
Error
TemplateDoesNotExist at /
homepage.html
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 4.1.5
Exception Type: TemplateDoesNotExist
Exception Value:
homepage.html
Exception Location: C:\Users\Django\first_proj\lib\site-packages\django\template\loader.py, line 19, in get_template
Raised during: travello.views.homepage
Directory structure:
travello
|-views.py
travellProj
|-templates -- > homepage.html
|-urls.py
|-setting.py
Your templates folder should be at the root of your site. Let see how it should look like:
Project_folder
|-travelproj <-- Your site configuration folder
|-|-urls.py
|-|-wsgi.py
|-|-asgi.py
|-|-.......
|-travello <-- this is an application
|-|-views.py
|-|-urls.py
|-|-templates <-- templates for this app only
|-|-|-travello
|-|-|-|-template1.html
|-|-|-|-.......
|-|-.......
|-templates <- This is the templates folder for your site
|-|-homepage.html
|-|-..........
|-manage.py
|-requirements.txt
So in your case your templates folder is in your site configuration folder which is not a good practice. you have to move it one step higher.
Good practices tips:
At the root of your site (same level than manage.py) you have a templates folder which will contain the templates commons to all your applications.
In each application you have a folder templates/app_name which contain all the templates specifics for this application.
You have the same architecture for statics.
Inside templates create another new directory by your app name travello then keep the html file inside the travello directory
travello
| templates/travello/homepage.html
|-views.py
travellProj
|-urls.py
|-setting.py
Then views should be like
def homepage(request):
return render(request,'travello/homepage.html')
I am having a strange issue using the built in password_rest view of django(1.8). In the documentation they say that the template name defaults to registration/password_reset_form.html. Keeping that in mind, I didn't give any template name in my urls.py, thinking that django will load the default template.Here is my url for the password reset
urls.py
url(r'^password_reset$', auth_views.password_reset, name='password_reset'),
When I click the forgot password link,
<p><a href={% url 'password_reset' %}> Forgot your password?</a></p>
which executes the password_rest view, I am getting Template DoesNotExist error and below is the error message
TemplateDoesNotExist at /accounts/password_reset
registration/password_reset.html
Template-loader postmortem
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
/home/vinothkumar/github/djtest/templates/registration/password_reset.html (File does not exist)
Using loader django.template.loaders.app_directories.Loader:
/home/vinothkumar/github/djtest/venv_new/lib/python3.4/site-packages/django/contrib/admin/templates/registration/password_reset.html (File does not exist)
/home/vinothkumar/github/djtest/venv_new/lib/python3.4/site-packages/django/contrib/auth/templates/registration/password_reset.html (File does not exist)
/home/vinothkumar/github/djtest/accounts/templates/registration/password_reset.html (File does not exist)
my question is why the template loader is looking for /registration/password_reset.html instead of loading the default /registration/password_reset_form.html?
I tried the same approach for password_reset_done, in this case it loads the default template /registration/password_reset_done.html. and everything there works fine.
So I changed the name of my registration template from user_form.html to register.html. I've also changed it in the urls.py file to reflect the new name, however when I try to go to the register page I get the following:
Exception Type: TemplateDoesNotExist
Exception Value:web/user_form.html
Template-loader postmortem
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
Using loader django.template.loaders.app_directories.Loader:
../swl/root/lib/pythpy2.7.egg/django/contrib/admin/templates/web/user_form.html (File does not exist)
../django/contrib/auth/templates/web/user_form.html (File does not exist)
../templates/web/user_form.html (File does not exist)
..tastypie/templates/web/user_form.html (File does not exist)
../bootstrap3/templates/web/user_form.html (File does not exist)
../web/templates/web/user_form.html (File does not exist)
Why would the template loader still be looking for the old filename?
edit: this is my url for register:
url(r'register/?$',
UserCreate.as_view(),
{
'template_name':'accounts/register.html'
},
name = 'register'),
Try to replace all user_form.html to registration.html in all files. You can use Find/replace in files feature (or something similar) of your text editor or IDE.
Change url to:
url(r'register/?$',
UserCreate.as_view(template_name='accounts/register.html'),
name = 'register')
The class-based views will attempt to use a default template name when no name is explicitly declared. (The CreateView uses (appname)/(model)_form.html) Your choices are:
Name your template using the default name
Specify the template in the URL (as in Vladimir's answer)
Specify the template name in the view code like so:
class UserCreate(CreateView):
template_name = "accounts/register.html"
Hope this helps
Restart the apache server.
For Ubuntu server 20:
/etc/init.d/apache2 restart
I am trying to load a register template for my first django site,
I put register.html file in /home/Desktop/projects/purple/purple/templates/registration.html
here but there is a error that is say to there is no file I did not understant that's why? can anyone have a idea?
Request Method: GET
Request URL: http...:127.0.0.1:8000/registration/
Django Version: 1.4
Exception Type: TemplateDoesNotExist
Exception Value: registration.html
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
/home/Desktop/projects/purple/purple/templates/registration.html (File does not exist)
Using loader django.template.loaders.app_directories.Loader:
/usr/local/lib/python2.7/dist-packages/django/contrib/auth/templates/registration.html (File does not exist)
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/registration.html (File does not exist)
Using loader django.template.loaders.eggs.Loader:
Given that the exception copy and pasted refers to:
/home/Desktop/projects/purple/purple/templates/registration.html
and can't find it... all of your problems lie in whether or not registration.html exists at the directory.
There are 2 possibilities:
File doesn't exist
cd into that exact directory and find out if it does.
Permissions
ls -lh /home/Desktop/projects/purple/purple/templates/registration.html
Make sure it's readable.
chmod 644 /home/Desktop/projects/purple/purple/templates/registration.html
do you have Registration directory inside Template directory??
if so then include this is your settings.py .
TEMPLATE_DIRS = (
BASE_DIR +'/Templates',
BASE_DIR +'/registration',
)
Because django is looking for registration.html in your Template directory instead of /template/registration.
see the order you mentioned in the question. watch the path.
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!