How to write and use custom template processors in Django

Jun 2018

Instead of repeatedly adding the same content is many places in your Django templates, you can write context processors to make it “globally” available for use in all templates. This helps to reduce on both code and data redundancy.

For example, Django uses the django.template.context_processors.csrf processor to add a token that is needed by the csrf_token template tag for protection against Cross Site Request Forgeries.

Django provides a very easy way of writing your own context processors. A context processor has a very simple interface: It’s a Python function that takes one argument, an HttpRequest object, and returns a dictionary that gets added to the template context. Each context processor must return a dictionary.

Custom context processors can live anywhere in your code base. All Django cares about is that your custom context processors are pointed to by the context_processors option in your TEMPLATES setting — or the context_processors argument of Engine if you’re using it directly.

As an example, lets say we are building an eCommerce shop. Several details such as the shop name and tagline may be required in several places in the templates. We can add a context processor to make this data available to all our templates.

Set up

To begin with, lets create a new Django project called shop and within this project a Django app which we’ll call main for simplicity.

$ django-admin startproject shop
$ cd shop
$ python manage.py startapp main

Next lets add the main app to the installed apps list in settings.py

# shop/settings.py
# ...
INSTALLED_APPS = [
    'main',

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

The context processor

Though the context processors can live anywhere in your project’s codebase, it conventional to keep them in a context_processors.py file in one of the apps.

In our case lets create this file in our main app and add the code to make the shop details available.

# main/context_processors.py
from django.conf import settings

def shop(request):
    kwargs = {
        'shop_name': settings.SHOP_NAME,
        'tagline': settings.SHOP_TAGLINE
    }
    return kwargs

And in our settings.py file we declare the two settings used above:

# shop/settings.py
# ....
SHOP_NAME = "Fashion Hub"
SHOP_TAGLINE = "The hub latest fashions and trends in clothing"
# ....

In the above case we’ve called our context_processors shop and it returns a dict containing the shop details. You can perform any of the tricks known to a python developer in your processor - pull data from the database, clean it up etc - as long as it returns a dictionary.

Lastly, to make our processor available, lets add its path to the context_processors option in the TEMPLATES setting:

# shop/settings.py
# ....
TEMPLATES = [
    {
        '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',
                'main.context_processors.shop',
            ],
        },
    },
]
# ....

That’s all. You can now access the two variables added by the shop context processor in your templates as you would any other variable. You can as also have as many context processors as you wish.

You can read more about this in Django’s documentation.

Subscribe to our Newsletter

Receive updates when we add new content. No spam or some funny tricks.