Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#24265 closed Bug (fixed)

jinja2 template backend results in KeyError

Reported by: Rob Hudson Owned by: Aymeric Augustin
Component: Template system Version: 1.8alpha1
Severity: Normal Keywords: multiple-template-engines 1.8-beta
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I created a new django 1.8a1 project. I made a couple settings changes, one of which was changing the single TEMPLATES config's 'BACKEND' to the jinja2 backend. I have no templates yet or URLs other than the default and attempted to visit the "It worked!" page but got a 500 instead.

Traceback follows:

Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 64, in __call__
    return self.application(environ, start_response)
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 191, in __call__
    response = self.get_response(request)
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/core/handlers/base.py", line 217, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/core/handlers/base.py", line 260, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/views/debug.py", line 100, in technical_500_response
    html = reporter.get_traceback_html()
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/views/debug.py", line 382, in get_traceback_html
    c = Context(self.get_traceback_data(), use_l10n=False)
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/views/debug.py", line 284, in get_traceback_data
    default_template_engine = Engine.get_default()
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/utils/lru_cache.py", line 125, in wrapper
    result = user_function(*args, **kwds)
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/template/engine.py", line 75, in get_default
    django_engines = [engine for engine in engines.all()
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/template/utils.py", line 104, in all
    return [self[alias] for alias in self]
  File "/Users/rob/.virtualenvs/tastytaps/lib/python2.7/site-packages/django/template/utils.py", line 93, in __getitem__
    backend = params.pop('BACKEND')
KeyError: 'BACKEND'

I attempted to debug this -- it appears that the template settings are getting processed twice. The first time it works. The 2nd time it doesn't since the 'BACKEND' key was popped off the dict. Changing pop to get in django/template/utils.py:L93 fixed the issue for me.

Change History (7)

comment:1 by Aymeric Augustin, 9 years ago

Keywords: multiple-template-engines added
Owner: changed from nobody to Aymeric Augustin
Status: newassigned

I thought I had taken care of copying before mutating... I'll take care of this.

comment:2 by Tim Graham, 9 years ago

Keywords: 1.8-beta added
Triage Stage: UnreviewedAccepted

comment:3 by Aymeric Augustin, 9 years ago

In order to reproduce this issue, I ran django-admin startproject mysite and defined TEMPLATES as follows:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [],
        'APP_DIRS': True,
    },
]

I'm getting a similar stack trace when jinja2 isn't installed. On Python 3, thanks to exception chaining, the root cause is obvious; not so much on Python 2. Rob, can you confirm that installing jinja2 solves the problem for you?

If so, this is an error reporting issue.

comment:4 by Aymeric Augustin, 9 years ago

Has patch: set

PR 4058 proposes two changes related to this issue.

After the first commit, Django's debug page reports the ImportError correctly instead of crashing in get_traceback_data().

That's a worthwhile improvement in itself. The debug page must be extremely robust. The multiple template engines refactor made it vulnerable to exceptions raised in Engine.get_default. However that commit addresses the symptoms rather than the root cause.

The second commit ensures that Django keeps raising the same exceptions when importing or initializing a template backends fails. For extra safety, I added one test for each case.

in reply to:  3 comment:5 by Rob Hudson, 9 years ago

Replying to aaugustin:

I'm getting a similar stack trace when jinja2 isn't installed. On Python 3, thanks to exception chaining, the root cause is obvious; not so much on Python 2. Rob, can you confirm that installing jinja2 solves the problem for you?

Yes, installing jinja2 fixes the issue. At the time I didn't have jinja2 installed -- I discovered it later after actually trying to create my first template.

comment:6 by Aymeric Augustin <aymeric.augustin@…>, 9 years ago

Resolution: fixed
Status: assignedclosed

In 44ad691558c88ac54483030b2c8b749788c4600e:

Fixed #24265 -- Preserved template backend loading exceptions.

If importing or initializing a template backend fails, attempting to
access this template backend again must raise the same exception.

comment:7 by Aymeric Augustin <aymeric.augustin@…>, 9 years ago

In aed1b1f6e5133f91c063f6f8b75729c4a18f99c7:

[1.8.x] Fixed #24265 -- Preserved template backend loading exceptions.

If importing or initializing a template backend fails, attempting to
access this template backend again must raise the same exception.

Backport of 44ad6915 from master

Note: See TracTickets for help on using tickets.
Back to Top