I have a base.html file where on the sidebar it loops through all the spaces inside of my Spaces model and displays them as links. I am wondering instead of passing these spaces through each view is there a way to just have them in the base template? I tried looking it up an came across template tags but I don't think those are what I am looking for.
Base.html
<div class="sidenav">
<h2>Spaces:</h2>
{% for space in spaces %}
<a href="/{{space}}">{{space}}</a>
{% endfor %}
</div>
Right now I am passing 'spaces' through my views but I don't want to have to do that in each view i create.
Any help would be appreciated!
CodePudding user response:
To have some variable global to all templates, Django provide context processor
. A context processor is a Python function that takes the request object as an argument and returns a dictionary that gets added to the request context.
You can add the spaces
objects in the context processor like this :
app_name/context_processors.py
from .app_name import Space
def spaces(request):
# It must return a dictionary don't forget
return {'spaces': Space.objects.all()}
In your context processor, you instantiate the space using the request object and make it available for the templates as a variable named spaces
.
settings.py
And next, you need to add this custom context processor in the TEMPLATES
variable in settings.py
like this :
TEMPLATES = [
{
# ...
'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',
# Customs
'app_name.context_processors.space',
],
},
]
template.html
Now you have access of spaces
variable on all templates of the project.
<div class="sidenav">
<h2>Spaces:</h2>
<!-- spaces variable is in all templates -->
{% for space in spaces %}
<a href="/{{space}}">{{space}}</a>
{% endfor %}
</div>