Suppose we have two or more views, where each view templates extends from base.html, and inside the base.html are context variables project_name
and company_name
:
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:
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 achive that more effeciently. but adding a context processor is the effecient for me.
so, following code snippet may make understand the process:
create a new python file in any of your app folder; preferably name it as 'context_processors.py' in that 'context_processors.py' file you many 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 golbally]
Then go the main project 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
],
},
},
]
afterward, you can access your context datas anywhere in the template like that:
<head>
<title>{{ project_name }}</title>
</head>
<body>
{{ company_name }}
{% block content %}{% endblock %}
</body>
</html>