TemplateDoesNotExist - file exists, no permissions issue - django

I'm receiving this error when trying to render a template in django:
TemplateDoesNotExist
...
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:
Here's my settings.py entry:
SETTINGS_PATH = os.path.normpath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(SETTINGS_PATH, 'template'),
)
Here's my view that's being called:
def handler(request):
if request.method == 'GET':
NewAppFormSet = modelformset_factory(Application)
return render_to_response(request, "template/apps.html",{"new_app_form":NewAppFormSet})
I've tried every possible combination of paths, adjusting permissions, etc. The real issue seems to be with the template loaders, as they are not recognizing any paths set forth in TEMPLATE_DIRS. I've hardcoded this string, to no avail. I've also ran python manage.py runserver with sudo / as root. I'm at a loss...

I had a very similar issue which was driving me crazy. It turns out that the book I was using to learn Python/Django did not say that I had to set the templates directory in settings.py expressly. Very confusing. I am using Python 2.6 & Django 1.3.1 - maybe a previous version automatically found the templates dir. Anyway, after pulling my hair out for a day and reading a lot on this site I figured out that I had to replace the default TEMPLATE_DIRS assignment with the following in settings.py:
# Find templates in the same folder as settings.py.
SETTINGS_PATH = os.path.realpath(os.path.dirname(__file__))
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(SETTINGS_PATH, 'templates'),
)
Thanks stackoverflow!!

I'm not sure what example I was following that specified the render_to_response shortcut method requires the views' request object to be passed, but it was as easy as changing it to:
return render_to_response("template/apps.html",{"new_app_form":NewAppFormSet()})

Try assigning SETTINGS_PATH with os.path.realpath:
SETTINGS_PATH = os.path.realpath(os.path.dirname(__file__))

By any chance, you might have copy-pasted the TEMPLATE_DIRS you have now, did you leave the default one lower down the SETTINGS file?

From my settings.py:
BASE_DIR = os.path.dirname(__file__)
def RELATIVE_PATH(*args):
return os.path.join(BASE_DIR, *args)
TEMPLATE_DIRS = (
RELATIVE_PATH('template'),
)

what if you try
return render_to_response(request, "apps.html",{"new_app_form":NewAppFormSet})
instead of
return render_to_response(request, "template/apps.html",{"new_app_form":NewAppFormSet})

Related

Django Template Does Not Exist

I know this has been covered already but none of the solutions have worked for me. I have a basic django project and it cannot find the template. Here is my views.py:
now = datetime.datetime.now()
t = get_template('index.html')
html = t.render(Context({'current_date' : now}))
return HttpResponse(html)
This is my TEMPLATE_DIRS in settings.py. The project is specified under INSTALLED_APPS
TEMPLATE_DIRS = (
'/Users/Howie/Desktop/djangoCode/mysite/Movies/templates/',
)
This is the error I get every time
Template-loader postmortem:
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
C:\Users\Howie\Desktop\djangoCode\mysite..\templates\index.html (File does not exist)
Using loader django.template.loaders.app_directories.Loader:
C:\Python34\lib\site-packages\django-1.7.2-py3.4.egg\django\contrib\admin\templates\index.html (File does not exist)
C:\Python34\lib\site-packages\django-1.7.2-py3.4.egg\django\contrib\auth\templates\index.html (File does not exist)
C:\Users\Howie\Desktop\djangoCode\mysite\Movies\templates\index.html (File does not exist)
I don't understand why django cant find my index.html file. I've tried moving the templates folder into the app itself(named Movies) and I've also had it in the root project folder but both of those didn't work. Any insight would be helpful.
The app_directories.Loader is enabled by default. This means you can put your template in an app/templates directory and be done. No need for TEMPLATE_DIRS and/or TEMPLATE_LOADERS settings. Just out of the box Django:
project/app/views.py
project/app/templates/index.html
get_template('index.html')
It's even better to use subdirectories:
project/app/views.py
project/app/templates/app/index.html
get_template('app/index.html')
This to avoid a index.html from some other app to take precedence.
If you really want a template folder in the root of your project, than don't use hardcoded paths. Do something like this:
from os.path import abspath, dirname, join, normpath
from sys import path
SITE_ROOT = dirname(dirname(abspath(__file__)))
TEMPLATE_DIRS = (
normpath(join(SITE_ROOT, 'templates')),
)
i had the same problem only to find out it was a typo error, i wrote templates
template/file_name/
as template which is not the Django way. The "s" is necessary
templates/file_name/

TemplateDoesNotExist Django Error

I am trying to build a login page form. In my urls.py, I have linked the file to the built in Django login view, and pass in the path to a template directory. I have login folder inside the template and login.html file inside the login folder.
(r'^login/$', 'django.contrib.auth.views.login', {
'template_name': 'login/login.html'
}),
In settings.py, I have provided the directory where my templates are being stored.
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__),'templates'),
)
When I run the runserver command, it shows TemplateDoesNotExist
Exception Type: TemplateDoesNotExist
Exception Value:login/login.html
For anyone experiencing the same problem, it turns out the template path was incorrect. I needed to use '../templates', instead of 'templates' in settings.py:
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__),'../templates'),
)
A better approach would be define your Directories in another settings file, to alleviate the need to use ugly relative path in your template dirs:
// _paths.py
SETTINGS_DIR = os.path.dirname(__file__)
// _templates.py
from settings/_paths.py import SETTINGS_DIR
TEMPLATE_DIRS = (
os.path.join(SETTINGS_DIR, 'templates'),
)
Adjust accordingly based on your folder structure.

Adding expire header for Django static files on Heroku

I'm trying to optimize my webpage and am having trouble setting expiration date headers on my static files.
I am running django-1.5, python-2.7.3.
Here's my cache settings in settings.pyso far:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(PROJECT_ROOT, 'cache/'),
}
}
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 5 * 60
CACHE_MIDDLEWARE_KEY_PREFIX = ''
MIDDLEWARE_CLASSES = (
'django.middleware.cache.UpdateCacheMiddleware',
...
'django.middleware.cache.FetchFromCacheMiddleware',
)
And my static file settings in settings.py:
import os.path
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(PROJECT_DIR, '..'))
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles/')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR, 'static'),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
The closest advice I've found was here, but I'm unable to modify the .htaccess files on Heroku.
Any help is greatly appreciated. Thanks!
The django staticfiles app does not provide out of the box support for custom headers. You'll have to hack together your own view to serve up the files and add custom headers to the HttpResponse.
But You should not be serving your static files using Django. This is a terrible idea.
Django is single-threaded, and blocking. So every time you're serving a user a static file, you're literally serving nothing else (including your application code, which is what Django is there for).
Django's staticviews file is insecure, and unstable. The documentation specifically says not to use it in production. So do not use it in production. Ever.
In production you shouldn't serve static files with Django. See the warning boxes on this page: https://docs.djangoproject.com/en/1.4/ref/contrib/staticfiles/#static-file-development-view
In development, Django's contrib.staticfiles app automatically serves staticfiles for you by overwriting the runserver command. This way you can't control the way it serves the static files.
You can prevent the staticfiles app from serving the static files by adding the --nostatic option to the runserver command:
./manage.py runserver --nostatic
Then you can write an url config to manually serve the static files with headers you want:
from functools import wraps
from django.conf import settings
from django.contrib.staticfiles.views import serve as serve_static
from django.conf.urls import patterns, url
urlpatterns = patterns('', )
if settings.DEBUG:
def custom_headers(view_func):
#wraps(view_func)
def wrapper(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
response['Custom-header'] = 'Awesome'
response['Another-header'] = 'Bad ass'
return response
return wrapper
urlpatterns += patterns('',
url(r'^static/(?P<path>.*)$', custom_headers(serve_static)),
)
If you want your manage.py to have the --nostatic option on by default, you can put this in your manage.py:
if '--nostatic' not in sys.argv:
sys.argv.append('--nostatic')
I think since you are hosting your project on heroku , the generally accepted practice seems to be using S3 for serving static files.
Have a look at this question :
Proper way to handle static files and templates for Django on Heroku
I am not too sure about this but I am sure you should be able to change headers while serving files from S3 atleast this SO question seems to suggest that way
Is it possible to change headers on an S3 object without downloading the entire object?
Hope this helps

Trouble loading django admin template

I am very new to Django and, following their tutorial, I am having issues loading a custom admin template (specifically, I am having trouble at the bottom of https://docs.djangoproject.com/en/1.4/intro/tutorial02/).
I have updated my TEMPLATE_DIRS so it looks like:
TEMPLATE_DIRS = (
'/Users/myname/Developer/Eclipse/templates/admin',
)
I have also tried:
TEMPLATE_DIRS = (
'/Users/myname/Developer/Eclipse/templates/admin/base_site.html',
)
The path for where I am storing this custom template follows:
"/Users/myname/Developer/Eclipse/templates/admin" (copy and pasted directly from file info)
Could someone point out what I am doing wrong? Thanks in advance.
Unless you don't use your admin folder for all the templates use this (I guess you want to overwrite admin templae. So admin folder should be subfolder of your template folder):
TEMPLATE_DIRS = (
'/Users/myname/Developer/Eclipse/templates/',
)
PROJECT_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates"),)

Django view - load template from calling app's dir first

I try to keep a somewhat consistent naming scheme on my HTML templates. I.e. index.html for main, delete.html for delete page and so forth. But the app_directories loader always seems to load the template from the app that's first alphabetically.
Is there any way to always check for a match in the calling app's templates directory first?
Relevant settings in my settings.py:
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.load_template_source',
'django.template.loaders.filesystem.load_template_source',
)
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates'),
)
I've tried changing the order of TEMPLATE_LOADERS, without success.
Edit as requested by Ashok:
Dir structure of each app:
templates/
index.html
add.html
delete.html
create.html
models.py
test.py
admin.py
views.py
In each app's views.py:
def index(request):
# code...
return render_to_response('index.html', locals())
def add(request):
# code...
return render_to_response('add.html', locals())
def delete(request):
# code...
return render_to_response('delete.html', locals())
def update(request):
# code...
return render_to_response('update.html', locals())
The reason for this is that the app_directories loader is essentially the same as adding each app's template folder to the TEMPLATE_DIRS setting, e.g. like
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'app1', 'templates'),
os.path.join(PROJECT_PATH, 'app2', 'template'),
...
os.path.join(PROJECT_PATH, 'templates'),
)
The problem with this is that as you mentioned, the index.html will always be found in app1/templates/index.html instead of any other app. There is no easy solution to magically fix this behavior without modifying the app_directories loader and using introspection or passing along app information, which gets a bit complicated. An easier solution:
Keep your settings.py as-is
Add a subdirectory in each app's templates folder with the name of the app
Use the templates in views like 'app1/index.html' or 'app2/index.html'
For a more concrete example:
project
app1
templates
app1
index.html
add.html
...
models.py
views.py
...
app2
...
Then in the views:
def index(request):
return render_to_response('app1/index.html', locals())
You could even write a wrapper to automate prepending the app name to all your views, and even that could be extended to use introspection, e.g.:
def render(template, data=None):
return render_to_response(__name__.split(".")[-2] + '/' + template, data)
def index(request):
return render('index.html', locals())
The _____name_____.split(".")[-2] assumes the file is within a package, so it will turn e.g. 'app1.views' into 'app1' to prepend to the template name. This also assumes a user will never rename your app without also renaming the folder in the templates directory, which may not be a safe assumption to make and in that case just hard-code the name of the folder in the templates directory.
I know this is an old thread, but I made something reusable, that allows for simpler namespacing. You could load the following as a Template Loader. It will find appname/index.html in appname/templates/index.html.
Gist available here: https://gist.github.com/871567
"""
Wrapper for loading templates from "templates" directories in INSTALLED_APPS
packages, prefixed by the appname for namespacing.
This loader finds `appname/templates/index.html` when looking for something
of the form `appname/index.html`.
"""
from django.template import TemplateDoesNotExist
from django.template.loaders.app_directories import app_template_dirs, Loader as BaseAppLoader
class Loader(BaseAppLoader):
'''
Modified AppDirecotry Template Loader that allows namespacing templates
with the name of their app, without requiring an extra subdirectory
in the form of `appname/templates/appname`.
'''
def load_template_source(self, template_name, template_dirs=None):
try:
app_name, template_path = template_name.split('/', 1)
except ValueError:
raise TemplateDoesNotExist(template_name)
if not template_dirs:
template_dirs = (d for d in app_template_dirs if
d.endswith('/%s/templates' % app_name))
return iter(super(Loader, self).load_template_source(template_path,
template_dirs))
The app_loader looks for templates within your applications in order that they are specified in your INSTALLED_APPS. (http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types).
My suggestion is to preface the name of your template file with the app name to avoid these naming conflicts.
For example, the template dir for app1 would look like:
templates/
app1_index.html
app1_delete.html
app1_add.html
app1_create.html