[Django]-Pass variable from middleware to templates

8👍

You may create a template context processor, first create a python file with a method that returns a dictionary with the info you need then add the route to this file in your project settings, using your example:

create a file context_processors.py on your app:

 from myapp.models import MyModel

 def my_context(request):
    context_data = dict()
    context_data['notification_count'] = MyModel.objects.all().count()
    return context_data

The add the context processor in your settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    #  ...
    'myapp.context_proccessors.my_context',
)

The you can use the ‘variable’ in any template:

<p>Count: {{ notification_count }}</p>

3👍

You can define a context processor function and add it to TEMPLATE_CONTEXT_PROCESSORS list defined in settings.py.

Let’s assume you have a file named project/context_processors.py, you can create a function that basically passes your value to all templates.

def notification_count(request):
    return {'notification_count': 2}

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'context_proccessors.notification_count',
)

Calling {{notification_count}} in your template will return 2.

You can take a look at the official documentation for more info about context processors.


Second approach would be, as you said, using middleware. However, I think that would be an overkill since you can do much more complicated calculations via middlewares.

middlewares.py

class NotificationsMiddleware(object):
    def process_template_response(self, request, response):
        if not ('notification_count' in response.context_data):
            response.context_data['notification_count'] = 2
        return response

Please note that, you should add the middleware into MIDDLEWARE_CLASSES list defined in your settings file.

MIDDLEWARE_CLASSES += ('middlewares.NotificationsMiddleware',)

Please see the middleware documentation for more information on how to alter request-response cycle in Django framework.

Hope this helps.

3👍

Middleware allows you to bind data to the request, meaning if you use Middleware and not a Context Processor, you can access this universal variable data in both templates and views, or actually anywhere where a request object is used throughout your codebase.

In my mind, this makes Middleware superior to Context Processors if you actually need a universal variable that is available everywhere. In short, and according to the docs: https://docs.djangoproject.com/en/2.2/topics/http/middleware/ Middleware is called on every view call.

Here is a simple example using your code and Middleware

class NotificationsMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):

        # I am showing this as a standard var not a dict as you originally had it, 
        # for simplicity, this is now a request attribute called notification_count
        request.notification_count = 2

        response = self.get_response(request)

        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        # You don't need this method for the middleware to work anymore
        # with Django as the __call__ method covers it, so you can delete it.
        pass

Now pass the Custom Middleware to settings like so:

MIDDLEWARE = [
    ...
    # custom middleware
    '[YOUR-PATH].NotificationsMiddleware'
]

Now you can call the variable in any template like so:

{{ request.notification_count }}

Or in any view, like so:

def index(request):

    print(' Notification Count =', request.notification_count)
    ...
    return render(request, 'index.html', { })

Leave a comment