Home > Back-end >  How to efficiently factor out similar contexts from multiple views in django?
How to efficiently factor out similar contexts from multiple views in django?

Time:09-01

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>
  • Related