I have come to a point where I need to pass certain variables to all of my views (mostly custom authentication type variables).
I was told writing my own context processor was the best way to do this, but I am having some issues.
My settings file looks like this
TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth","django.core.context_processors.debug","django.core.context_processors.i18n","django.core.context_processors.media","django.contrib.messages.context_processors.messages","sandbox.context_processors.say_hello", )
As you can see, I have a module called 'context_processors' and a function within that called 'say_hello'.
Which looks like
def say_hello(request):return {'say_hello':"Hello",}
Am I right to assume I can now do the following within my views?
{{ say_hello }}
Right now, this renders to nothing in my template.
My view looks like
from django.shortcuts import render_to_responsedef test(request):return render_to_response("test.html")
Best Answer
The context processor you have written should work. The problem is in your view.
Are you positive that your view is being rendered with RequestContext
?
For example:
def test_view(request):return render_to_response('template.html')
The view above will not use the context processors listed in TEMPLATE_CONTEXT_PROCESSORS
. Make sure you are supplying a RequestContext
like so:
def test_view(request):return render_to_response('template.html', context_instance=RequestContext(request))
According to the django docs you can use render
as a shortcut instead of render_to_response with the context_instance argument:
Alternatively, use the
render()
shortcut which is the same as a call to render_to_response() with a context_instance argument that forces the use of a RequestContext.
Let's say you have a file structure like this:
YourDjangoProject├───project│ ├───__init__.py│ ├───asgi.py│ ├───settings.py│ ├───urls.py│ └───wsgi.py├───.env├───manage.py└───db.sqlite3
1) Anywhere, create a context_processors.py file
I'll create one in the project folder (with settings.py):
YourDjangoProject└───project├───...└───context_processors.py
2) Create a function in context_processors.py that accepts a HttpRequest object as an argument and returns a dictionary
A context processor is just a function that accepts an HttpRequest object as an argument and returns a dictionary.
Like this:
# project/context_processors.pydef site_email(request):return {'site_email': '[email protected]'}
3) Add this to your context_processors
setting in settings.py
(at the bottom for security reasons)
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [BASE_DIR / 'config' / 'templates'],'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','project.context_processors.site_email', # <- New context processor here],},},]
Now you'll be able to access the 'site_email' template variable on every single django template across your whole site.
Happy coding!
Since Django 1.8 you register your custom context processors like this:
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': ['templates'],'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','www.context_processors.instance',],},},]
assuming your context processor is in app www
in context_processors.py
If you’re using Django’s render_to_response()
shortcut to populate a template with the contents of a dictionary, your template will be passed a Context instance by default (not a RequestContext
). To use a RequestContext
in your template rendering, use the render()
shortcut which is the same as a call to render_to_response()
with a context_instance
argument that forces the use of a RequestContext
.