0

I have the following two apps located in my virtualenv: backend backoffice. The backoffice app has templates under:

backoffice/templates

So when I login into the Django shell, I can to do the following:

>>>from django.template.loaders.app_directories import Loader
>>> list(l.get_template_sources('index.html'))
[u'/var/www/venv2.7/lib/python2.7/site-packages/django/contrib/auth/templates/index.html', u'/var/www/venv2.7/lib/python2.7/site-packages/backoffice/templates/index.html', u'/var/www/venv2.7/lib/python2.7/site-packages/django/contrib/admin/templates/index.html']

So it seems the template is correctly found (l.load_template_source(('index.html') is also working).

However, when I access my home page via the browser I get an error:

TemplateDoesNotExist at /

Can someone help me solve the puzzle? What am I missing?

update: full trackback

Request Method: GET
Request URL: http://192.168.211.140/

Django Version: 1.5.1
Python Version: 2.7.6
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'backoffice',
 'backend',
 'django.contrib.admin')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')

Template Loader Error:
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
Using loader django.template.loaders.app_directories.Loader:
/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/contrib/auth/templates/index.html (File does not exist)
/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/contrib/admin/templates/index.html (File does not exist)



Traceback:
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  25.                 return view_func(request, *args, **kwargs)
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/backoffice/views.py" in start_page
  177.     return render(request, 'index.html', context)
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/shortcuts/__init__.py" in render
  53.     return HttpResponse(loader.render_to_string(*args, **kwargs),
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/template/loader.py" in render_to_string
  170.         t = get_template(template_name)
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/template/loader.py" in get_template
  146.     template, origin = find_template(template_name)
File "/var/www/backoffice/venv2.7/lib/python2.7/site-packages/django/template/loader.py" in find_template
  139.     raise TemplateDoesNotExist(name)

Exception Type: TemplateDoesNotExist at /
Exception Value: index.html
oz123
  • 27,559
  • 27
  • 125
  • 187

2 Answers2

3

Ah, I want to cry, how can Django be so tricky ...

I just updated settings.INSTALLED_APPS:

# It was like this
INSTALLED_APPS = ( 

  'django.contrib.auth',
   ...
   'backoffice', 
   'backend',   
   'django.contrib.admin' #!!! NOT ALLOWED HERE
)

# This will workd
INSTALLED_APPS = ( 

  'django.contrib.auth',
   ...
   'django.contrib.admin' # ALLOWED HERE
   'backoffice', 
   'backend',   
)
oz123
  • 27,559
  • 27
  • 125
  • 187
1

The order of INSTALLED_APPS is important. However, a good standard practice to prevent collisions on template names when you use the app directory loader is to namespace your templates by the app name in its director structure, such that:

Your templates for app backoffice live in:

backoffice/templates/backoffice/

In implementation, you would be rendering the template "backoffice/index.html" which will never collide with a template in django.contrib.admin. This design pattern plays nice with pluggable apps. Should you ever release backoffice as a pluggable app, other users can override its templates in their main template directory by simply adding a backoffice directory.

Casey Kinsey
  • 1,451
  • 9
  • 16