Django Custom Context Preprocessors – Share Data across all Templates

In this post, we’ll be looking at Django Context Preprocessors. In this post, we’ll learn about uses of context Preprocessors
how we can use them in our project.

Table of Contents

Introduction

Let us consider a scenario where you have a blog website and on all pages of that site, you would want to display the total number of blogs on your site.
This is a simple example and there can be other similar examples seen in most of the websites where the same data like company name, address, and email, etc are displayed either on header or footer of that particular website.

Now we want to display those details on all pages. One way to do this is we pass value each time through views or
we can have Context Preprocessors to do that for us. This will completely get rid of unnecessary work or extra work on views.

So now we know what Context Preprocessors does let us do it practically.

Setting up the project

Below are command to setup project

django-admin startproject mysite

Use the below command to create an app.

django-admin startapp my_context

Create a database and in settings.py file configure it

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite',
        'USER': 'root',
        'PASSWORD': '....',
        'HOST': 'localhost',   # Or an IP Address that your DB is hosted on
        'PORT': '3306',
        'OPTIONS': {
            'sql_mode': 'traditional',
        }
    }
}

# Register app my_context in settings.py file
INSTALLED_APPS = [
    '...',
    'my_context.apps.MyContextConfig',
]

Create urls.py file is app my_context and include it to project root’s urls.py file.
In my_context/urls.py.

from django.urls import path
from my_context import views

app_name = "my_context"
urlpatterns = [
    path("", views.home, name="home")
]

In mysite/urls.py.

from django.contrib import admin
from django.urls import path, include
urlpatterns = [
    path('admin/', admin.site.urls, name='admin.index'),
    path('my_context/', include('my_context.urls'), name='my_context'),
]

Creating a Context Method

In-app my_context/models.py create a BlogModel.

from datetime import datetime
from django.db import models
from django.contrib.auth.models import User

class BlogModel(models.Model):

    BLOG_STATUS = (
        ('PUBLISH', 'Publish'),
        ('DRAFT', 'Draft'),
    )

    blog_id = models.AutoField(primary_key=True)
    user = models.ForeignKey( User, on_delete=models.CASCADE, related_name='blogs' )
    title = models.CharField(max_length=255)
    content = models.TextField(blank=True, null=True)
    status = models.CharField(max_length=7, choices=BLOG_STATUS)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta():
        db_table = 'blogs'
        verbose_name = 'Blog'
        verbose_name_plural = 'Blogs'

    def __str__(self):
        return self.title

Now we need to migrate this model to the database to do that enter below commands in the terminal.

python manage.py makemigrations my_context

python manage.py migrate

To create a method for context that returns data on every request throughout the application.
Create a context.py file in app my_context.
In my_context/context.py.

from blogs.models import BlogModel

def count_blog_posts(request):
    context = {
        "blog_count" : BlogModel.objects.all().count()
    }
    return context

We have created a function count_blog_posts which takes request as an argument and inside the function we can state our business logic.Here we have created a dictionary variable context and key blog_count counts the total blogs.

We have one step left to do that is to tell Django to use this method. This must be mentioned in settings.py file in near TEMPLATES section.
Give function path to the context we just created and add below. This is how you should specify.

`<app_name>.<file_name>.<function_name>`
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'mysite/templates'),
        ],
        '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',
                'my_context.context.count_blog_posts', # add the context function here
            ],
        },
    },
]

Creating Views and Templates

Now we can test it by creating views and templates.
In my_context/views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def home(request):
    template_path = "context_preprocessor/home.html"
    return render(request,template_path,{})

Create a template name it home.html.
We recommend you create a template file in this path my_site/my_context/templates/my_context/home.html or else you may get template not found error.
In my_context/templates/my_context/home.html.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Home</title>
</head>
<body>
    <h3>Total number of blog posts on website are : {{blog_count}} nos</h3>
</body>
</html>
Final Output - Django Custom Context Preprocessors - Share Data across all Templates
Final Output – Django Custom Context Preprocessors – Share Data across all Templates

Conclusion

We have come to the final part of our post  Django Custom Context Preprocessors – Share Data across all Templates. For any suggestion comment below.

Related Posts

Summary
Review Date
Reviewed Item
Django Custom Context Preprocessors - Share Data across all Templates
Author Rating
51star1star1star1star1star
Software Name
Django Framework
Software Name
Windows Os, Mac Os, Ubuntu Os
Software Category
Web Development