[Django]-Template Language for Django which does not silently fail on exception?

4đź‘Ť

One solution would be to change your template backend to jinja2 (which is supported “natively” by Django) following the documentation.

An in-depth explanation on how jinja2 django backend handles the undefined variable issue, can be found here (notation mine):

Invalid template variables

You can set various behaviors when an invalid variable is encountered
in Jinja templates. Django sets Jinja with two default behaviors, one
for when DEBUG=True — a common setting in development — and the
other for when DEBUG=False — a common setting in production.

If DEBUG=True and an invalid variable is set in a Jinja template,
Jinja uses the jinja2.DebugUndefined class to process it. The
jinja2.DebugUndefined class outputs the variable verbatim for
rendering (e.g. if the template has the {{foo}} statement and the
variable doesn’t exist in the context, Jinja outputs {{foo}}, making
it easier to spot an invalid variable).

If DEBUG=False and an invalid variable is set in a Jinja template,
Jinja uses the jinja2.Undefined class to process it. The
jinja2.Undefined class outputs a blank space in the position of the
variable for rendering (e.g. if the template has the {{bar}} statement
and the variable doesn’t exist in the context, Jinja outputs a blank
space). It’s worth mentioning this last behavior aligns with the
default behavior of invalid variables in Django templates.

In addition to the jinja2.DebugUndefined and jinja2.Undefined classes,
Jinja also supports the jinja2.StrictUndefined class. The
jinja2.StrictUndefined class is used to generate an immediate error
instead of proceeding with rendering, which is helpful for quicker
diagnosis of invalid variables. However, be aware this last class
changes its behavior based on the DEBUG variable, it either generates
a stack error with the invalid variable name (i.e. when DEBUG=True) or
it generates a standard HTTP 500 error page (i.e. when DEBUG=False).

If you like to set the StrictUndefined option on your template you can use the following example from the same source:

Listing 4-4. Generate error for invalid variables in Jinja with
jinja2.StrictUndefined

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))

import jinja2

TEMPLATES = [    
    { 
        'BACKEND':'django.template.backends.jinja2.Jinja2',
        'DIRS': ['%s/jinjatemplates/'% (PROJECT_DIR),],
        'APP_DIRS': True,
        'OPTIONS': {
            'undefined':jinja2.StrictUndefined
        },
    }            
]

As you can see in Listing 4-4, we first declare import jinja2 to gain
access to Jinja’s classes in settings.py. Next, we declare the
undefined key inside the OPTIONS parameter and assign it the Jinja
class to process invalid variables. In this case, we use the
jinja2.StrictUndefined class to get errors when invalid templates
variables are encountered, but you could equally use any of the other
two Jinja classes to handle invalid variables (i.e.
jinja2.DebugUndefined or jinja2.Undefined).

Finally, if you want to have a different behavior between DEBUG=True or DEBUG=False you can change the following in the TEMPLATES settings:

'OPTIONS': {
    'undefined': jinja2.DebugUndefined if DEBUG else jinja2.StrictUndefined
},

Utilizing jinja2’s debugging option on development and strict options on production (raising errors as is mentioned in the question).

👤John Moutafis

Leave a comment