Context processors are functions that take the current request object as an argument and return a dict of variables that are added to the context of the requested template. They allow for common information to be applied to all templates as needed.

More specifically, when we make a request to a Django application it goes through all the middleware and view functions defined in the app in order to generate a response. Once this has happened and we are at the point where a view function can return a TemplateResponse Django begins to render the required template.

While rendering the template, Django will look for context processors declared in our settings.py file. For each context processor, Django will call the function it is associated with and add the dictionary of variables to the template context, which can be used as part of the template itself (using Django Templates or Jinja2, for example).

Context Processors are particularly useful when information has to be available on every page of the website, such as:

  • A user’s cart on an e-commerce website
  • Site-wide navigation or a logo
  • User’s details, such as username, avatar, etc
  • Information for footers
  • Authentication data

It is possible to avoid the user context processors, but it would require including code in every view that fetches the required information, making the code-base significantly more unwieldy.

Using context processors

Built-in processors

There are many built-in processors included in Django:

  1. django.template.context_processors.debug: Provides debug information, such as debug and sql_queries, when DEBUG is set to True and the request comes from an internal IP address (e.g., 127.0.0.1).
  2. django.template.context_processors.request: Adds the current request object to the template context.
  3. django.contrib.auth.context_processors.auth: Provides authentication-related variables, such as user and perms.
  4. django.contrib.messages.context_processors.messages: Adds message-related variables, such as messages.

Custom processors

If we want to create our own processor we can define a function that takes a request object as an argument and returns a dictionary of variables. For example:

from myapp.models import SiteLogo
 
def site_logo_context(request):
	return {"logo" : SiteLogo.objects.first()}

Then, in settings.py we register the processor in the TEMPLATES section:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # Built-in processors
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                # Custom processor
                'myapp.context_processors.site_logo_context',
            ],
        },
    },
]