Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass variable from middleware to templates

I'm Django starter. So far I learned pass variable from view to template. But now I need pass variable to my main layout. I can pass it in each page's def in view. But its too much duplication. So I started learn about middleware.

I created middlewares.py and included it in settings. In middlewares.py file, how to pass variable to my main layout?

Below is my current middlewares.py content, I tried many ways and commented them out, because not working.

from django.db import connections
from django.shortcuts import render, redirect

class NotificationsMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):

        request.context_data['notification_count'] = 2
        response = view_func(request, *view_args, **view_kwargs)

        return response

    # def process_request(self, request):
    #     request.notification_count = 2
    #     return

    # def process_template_response(self, request, response):
    #     # response.context['notification_count'] = 2
    #     response.context_data['notification_count'] = 2
    #     # return response
    #     return render(request, 'main/locations.html')
like image 860
Gereltod Avatar asked Oct 28 '25 15:10

Gereltod


2 Answers

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>
like image 64
jacksboo Avatar answered Oct 31 '25 04:10

jacksboo


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', { })

like image 28
ViaTech Avatar answered Oct 31 '25 04:10

ViaTech



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!