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')
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>
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', { })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With