This is a very similar question to this SO thread on middleware and views communicating
We'd like to have our templates be given a standard set of context variables. So, a context processor seems appropriate, however, it doesn't seem like the context processor is view-aware. We'd previously been forced to inspect the call stack to get contextual information on what view was doing what.
That's where we saw the middleware thread as well as the process_view()
signature for a middleware that gives us a handle to the view.
This seemed closer to our needs, but didn't allow us to modify the context variable, neither did the other middleware methods.
So our intial idea bandied about was to modify the request object with all the global and contextual information we needed for our templates and force the templates to call from the {{request.something}}
for the specific information we need, such as {{request.viewname}}
.
So, our questions:
middleware.process_response
have an opportunity to modify the context or is it immutable?It's perfectly valid to set variables on the request in middleware - I do it all the time.
There's no way to use process_response
for this, as by then the template has already been rendered - at this point all you get is an HttpResponse
containing a bunch of HTML.
An alternative might be to wrap render_to_response
with your own function, which takes the context, together with the request and template, and modifies it as necessary before handing off to the actual render function. This has the advantage of modifying the actual context, but the disadvantage that you have to actually remember to call it in every view instead of the default function.
You could do it by using middleware and a context processor in tandem. The middleware knows about the view, and can set an attribute on the request. Then the context processor can move anything set on the request into the context.
For example:
class ExtraContextMiddleware(object):
"""
Adds extra context to the response for certain views.
Works in tandem with the extra_context context processor.
"""
context_map = {
#Adds the supplied context dict to the named views
'my_view_name': {'foo': 'Hello', 'bar': 'Goodbye'},
}
def process_view(self, request, view, *args, **kwargs):
try:
request.extra_context = self.context_map[view.func_name]
except KeyError:
pass
Then the context processor:
def extra_context(request):
"""Context processor for adding extra context.
Works in tandem with ExtraContextMiddleware."""
try:
return request.extra_context
except AttributeError:
return {}
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