Using Jinja2 with Django (1.8 onwards)

I have been using Jinja2 previously in my projects created with Flask. Recently however I wanted to use Jinja2 with Django for its potential performance boost (10 to 20 times faster compared to Django templates according to this) and interoperability with Nunjucks.

This post is aimed for people that are already familiar with the given techonologies. If you are just starting out with Django I would recommend on starting from their great tutorial here. Django also provides some simple instructions for Jinja2 here, but this post aims to open up and simplify the steps a little more.


First install and setup Jinja2

pip install Jinja2

and remember to add it to requirements.txt. Then add following template engine setting to TEMPLATES variable in settings.py

{
‘BACKEND’: ‘django.template.backends.jinja2.Jinja2’,
‘DIRS’: [],
‘APP_DIRS’: True,
‘OPTIONS’: {
‘environment’: ‘your-app.jinja2.environment’
},
}

so that the whole template settings looks something like this:

TEMPLATES = [
{
‘BACKEND’: ‘django.template.backends.jinja2.Jinja2’,
‘DIRS’: [],
‘APP_DIRS’: True,
‘OPTIONS’: {
‘environment’: ‘your-app.jinja2.environment’
},
},
{
‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
‘DIRS’: [],
‘APP_DIRS’: True,
‘OPTIONS’: {
‘context_processors’: [
‘django.template.context_processors.debug’,
‘django.template.context_processors.request’,
‘django.contrib.auth.context_processors.auth’,
‘django.contrib.messages.context_processors.messages’,
],
},
},
]

remember also to change Jinja2 options environment variable to the correct app name (change ‘your-app’ to whatever your application folder is called).

The options environment enables us to use certain functions in templates that we will setup next. Create jinja2.py file to your application folder (same place where the settings.py was) and add the following:

from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update({
‘static’: staticfiles_storage.url,
‘url’: reverse,
})
return env

This enables us to use Django template tags like {% url ‘index’ %} or {% static ‘path/to/static/file.js’ %} in our Jinja2 templates. As you can see, these template tags use the actual functions provided by Django. Following the Jinja2 way of calling functions in template you can use them like this:

Django’s:

{% url ‘index’ variable %}

is equivalent to:

{{url(‘index’, args=[variable])}}

in Jinja2. And for named variables you can use:

{{url('index', kwargs={'variable_key':variable}}}

Django’s

{% static ‘path’ %}

is equivalent to

{{ static(‘path’)}}

As you have probably already noticed you can basically add any functions to Jinja2 environment by adding them to jinja2.py file to make them usable in templates.

Finally setup folders

After you have setup setting properly you can simply create a Jinja2 folder anywhere you would create the templates folder. It should work automagically as Django is rather polished framework. Having both Django’s template engine and Jinja2 allows you to use both flexibly so for example you can still have the admin panel provided by Django and any other plugins you might want to use, that use Django templates. Be sure to read Jinja2 documentation also to learn more about how to use it.

Here is an example how one app folder structure might look for our project: