Context Processors
A context processor is a function that takes the request and returns a dictionary of variables, which Django merges into every template's context so those variables are available in all templates without each view passing them.
Learn Context Processors in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll see how Django merges context dictionaries, configure the context_processors list in the TEMPLATES setting, write your own custom processor, and understand the built-in request, auth, and messages processors.
When you render a template, Django doesn't just use the dictionary your view returns. It builds the final context by merging several dictionaries : one dictionary from each context processor listed in your settings, plus the dictionary your view passes. The processors run first, and then the view's values are layered on top, so a key from your view wins over the same key from a processor.
This is the mental model. In your settings, the processors are listed in TEMPLATES :
A context processor is just a function that accepts the request and returns a dictionary. By convention you put these functions in a file named context_processors.py inside your app. Suppose you want the current year and a set of navigation links to be available in every template — perfect for a footer and a shared navbar.
Then add its dotted path to the context_processors list so Django runs it on every request:
Now any template can use the values directly, with no view changes:
Most of the variables you take for granted in templates come from Django's built-in processors. The auth processor is the reason every template can reference {'{ }'} and {'{ }'} — the view never has to pass them. The request processor exposes {'{ }'} so you can read the current path or query parameters. The messages processor exposes flash messages.
A context processor must return a dictionary. Replace the blank so feature_flags makes show_beta available to every template.
❌ My processor variable isn't showing up in the template
You wrote the function but never added it to the settings list, so Django never calls it.
✅ Fix: add its dotted path (e.g. "myapp.context_processors.common_context" ) to context_processors in TEMPLATES["OPTIONS"] .
❌ TypeError: context processor didn't return a dictionary
Your function forgot the return , or returned None , so Django can't merge it.
✅ Fix: always end the processor with return {' '} — return an empty dict {' '} if there's nothing to add.
A built-in processor was removed from the list, so its variables are no longer injected.
✅ Fix: make sure the request , auth , and messages processors are still listed in context_processors .
Build two processors — one for theme/site name, one for a cart count — merge them, and confirm a per-view value overrides a processor default.
Lesson complete — your variables reach every template!
You learned how Django merges context dictionaries on each request, where to register processors in the TEMPLATES context_processors list, how to write a custom processor that returns a dict, and what the built-in request, auth, and messages processors give you for free.
🚀 Up next: Custom User Model — replace Django's default user with your own, using AbstractUser and AUTH_USER_MODEL.
Practice quiz
What does a Django context processor return?
- A rendered HTML string
- A dictionary merged into every template context
- An HttpResponse object
- A list of templates
Answer: A dictionary merged into every template context. A context processor takes the request and returns a dict that Django merges into the context of every rendered template.
Where do you register a custom context processor?
- In urls.py
- In the MIDDLEWARE setting
- OPTIONS
Answer: OPTIONS. You add the function's dotted path to the context_processors list in the TEMPLATES setting's OPTIONS.
Which built-in processor exposes {{ user }} and {{ perms }} to templates?
- django.contrib.auth.context_processors.auth
- django.template.context_processors.request
- django.contrib.messages.context_processors.messages
- django.template.context_processors.static
Answer: django.contrib.auth.context_processors.auth. The auth context processor makes user and perms available in every template.
What argument does a context processor function receive?
- The template name
- The response
- The view function
- The request
Answer: The request. A context processor is a function that accepts the current request object.
Which built-in processor exposes {{ request }} in templates?
- django.template.context_processors.request
- django.contrib.auth.context_processors.auth
- django.template.context_processors.csrf
- django.contrib.messages.context_processors.messages
Answer: django.template.context_processors.request. The request context processor adds the request object to the template context.
If a context processor and a view both set the same key, which wins?
- The processor value
- Neither — it raises an error
- The view value, merged last
- The first one alphabetically
Answer: The view value, merged last. Django merges processor dicts first, then the view's context, so the view value overrides the processor's.
What happens if a context processor returns None instead of a dict?
- Django ignores it silently
- Django raises a TypeError trying to merge it
- The page renders blank
- It returns an empty dict automatically
Answer: Django raises a TypeError trying to merge it. Django expects a dict to merge; returning None raises a TypeError.
Which built-in processor exposes flash {{ messages }}?
- django.template.context_processors.static
- django.contrib.messages.context_processors.messages
- django.template.context_processors.request
- django.contrib.auth.context_processors.auth
Answer: django.contrib.messages.context_processors.messages. The messages context processor exposes the messages framework's flash messages.
When should you prefer a context processor over passing a variable in the view?
- When the value is needed across many or all templates
- When the value is specific to one page
- When the value requires a heavy database query
- Never — views are always better
Answer: When the value is needed across many or all templates. Use a processor for site-wide values; pass page-specific values directly from the view.
Why should context processors stay fast?
- Templates cache them once
- They only run in DEBUG mode
- They run on every request, so a slow one slows every page
- Django limits them to one per project
Answer: They run on every request, so a slow one slows every page. Because Django calls every processor on each request, a slow processor slows down the whole site.