creating my own context processor in django
Solution 1
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))
Solution 2
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.
Solution 3
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.py
def 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!
Solution 4
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
Solution 5
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
.
Comments
-
dotty almost 2 years
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_response def test(request): return render_to_response("test.html")
-
dotty about 14 yearsThe 'context_instance' is what was missing! Thanks TM
-
dotty about 14 yearsFollow up, how come i need this context_instance? How come i don't need this if i use django's auth system?
-
TM. about 14 yearsDjango's built in views handle this for you (they use a
RequestContext
). Think about the context processor that you made. It takesrequest
as an argument. That means you need to somehow give the current request to the rendering logic.RequestContext
basically just handles the simple logic of looping through all the context processors and passing the current request to them, then updating the page context with the results. -
dotty about 14 yearsCould i modify my view to request the context?
-
TM. about 14 years@dotty Not sure what you mean by "request the context".
-
suhailvs almost 11 years@TM.
return render_to_response('template.html', context_instance=RequestContext(request))
is old fasion, i thinkreturn render(request,'template.html')
is more DRY -
TM. almost 11 years@suhail doesn't that require a special third-party decorator on the view function? The answer is out of date in general (over 3 years old!), probably these days there would be a class-based view here.
-
fabspro over 10 yearsIndeed, these days that is possible.
-
ash over 2 yearsVery Very sorry @Zack But it's a really awesome answer. Given you an upvote. Really helped me to understand a very important concept of Django. Seen your profile You really have a Great vision for Humanity and the future. Hope to see you succeed in your vision. keep Smiling like that.