Suppose we have two or more views, where each view templates extends from base.html, and inside the base.html file are context variables project_name
and company_name
:
File base.html
<!DOCTYPE html>
<html>
<head>
<title>{{ project_name }}</title>
</head>
<body>
{{ company_name }}
{% block content %}{% endblock %}
</body>
</html>
Then we would have to add the above-mentioned contexts to our views as follow:
File views.py
def view1(request)
context = {
"view1 data": "some data",
"project_name": "Project Name",
"company_name": "Company Name",
}
return render(request, "view1.html", context)
class View2(DetailView):
template_name = "view2.html"
model = SampleModel
def get_context_data(self, **kwargs):
context = super(View2, self).get_context_data(**kwargs)
context["view2 data"] = "sample data"
context["project_name"] = "Project Name"
context["company_name"] = "Company Name"
return context
How do we write an efficient code so that our views will look like as follows, i.e. the common contexts project_name
and company_name
are factored out somewhere else yet will still be displayed in the base.html?
Desired views.py
def view1(request)
context = {
"view1 data": "some data",
}
return render(request, "view1.html", context)
class View2(DetailView):
template_name = "view2.html"
model = SampleModel
def get_context_data(self, **kwargs):
context = super(View2, self).get_context_data(**kwargs)
context["view2 data"] = "sample data"
return context
Understandably, function-based views and class-based views may function differently so there may be different solutions to each of them.
CodePudding user response:
To my knowledge, I know there are approaches to achieve that more efficiently. But adding a context processor is the efficient for me.
So, the following code snippet may make understanding the process easier:
Create a new Python file in any of your app folders; preferably name it as 'context_processors.py'. In that 'context_processors.py' file you may write:
def any_function_name(request):
any_dictionary_name = {
"view1 data": "some data",
"project_name": "Project Name",
"company_name": "Company Name",
}
return any_dictionary_name
(Note: Like that, you can even write queryset to get any data and make it available globally)
Then go the main project's file settings.py:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
'DIRS': [],
'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',
'your_app_name.context_processors.any_function_name' #Add the file reference here
],
},
},
]
Afterwards, you can access your context data anywhere in the template like this:
<!DOCTYPE html>
<html>
<head>
<title>{{ project_name }}</title>
</head>
<body>
{{ company_name }}
{% block content %}{% endblock %}
</body>
</html>