I'm very new to Django and in my application I have a dynamic navbar on top. The context are passed in as context. Imagine it looks like this:
<ul>
{% for link in links %}
<li><a href="{{ link }}"></a></li>
{% endif %}
</ul>
The views may look like this:
def nav_links():
# Display links to first 5 MyModel objects
objects = MyModel.objects.all()[:5]
return [o.get_absolute_url() for o in objects]
def index(request):
return render("request", "app/index.html", context={"links": nav_links()})
def page1(request)
some_data = ...
return render("request", "app/page1.html", context={"links": nav_links(), "data": some_data})
def page2(request)
return render("request", "app/page2.html", context={"links": nav_links()})
...
Currently, I need to pass in links
as context in each of the views. This is obviously bad design.
Is there a way to pass in the same context for all views?
CodePudding user response:
You can work with a context processor, this is a function that each time runs to populate the context. Such context processor looks like your nav_links
, except that it should be a dictionary with the variable name(s) and corresponding value(s):
# app_name/context_processors.py
def links(request):
from app_name.models import MyModel
objects = MyModel.objects.all()[:5]
return {'links': [o.get_absolute_url() for o in objects]}
Then you can register the context processor in the settings.py
with:
# settings.py
# …
TEMPLATES = [
{
# …,
'OPTIONS': {
'context_processors': [
# …,
'app_name.context_processors.links'
],
},
},
]