Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a variable in middleware to be accessed in the template

Tags:

django

I seem to be having difficulty setting a variable in one of my middleware classes that I can then access in the template layer.

The basic layout is this:

class TheMiddleware(object):
    def __init__(self, etc):
        stuff...

    def process_response(self, request, response):
        request.my_var = "whatever"
        return response

Then on the template for a different view I have:

{% custom_tag arg_a %}

Which is is a template tag that should return the variable from the request:

@register.simple_tag
def custom_tag(arg_a):
    return threading.currentThread().request.my_var

This errors out with "Caught AttributeError while rendering: 'WSGIRequest' object has no attribute 'my_var'"

I thought it might be the way I was accessing the request in the template tag. So I added django.core.context_processors.request to my TEMPLATE_CONTEXT_PROCESSORS as in This question and tried passing the request object to the tag, then accessing request directly from the template but with no luck.

I think I lack an understanding on how request objects work. Is it possible to assign a variable to a request object and pick that variable up several views on? I thought the request object was passed through the views, but it seems that instead a new instance is generated.

If that is the case, how would you go about storing a global variable within middleware that you could then access from any point in your app, be it in a view or a template?

Update:

To clear up the confusion (whether mine or others I'm not sure!) I'm not trying to set the request variable in the process_response middleware of a view and then pick it up in the template of that same view. I understand that that wouldn't work because the template has been processed before the variable is saved. (This is a deliberate act on my part).

I have two views, view1 and view2 view one has a decorator that causes the middleware to set the variable in the request. It is the view2 template, which comes after the variable has been set, that I wish to access the variable.

like image 499
PT114 Avatar asked Mar 26 '13 09:03

PT114


People also ask

What do you use middleware for in Django?

Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level “plugin” system for globally altering Django's input or output. Each middleware component is responsible for doing some specific function.


2 Answers

You trying to set variable during processing of response in your middleware.

I think you should be implementing process_request() instead to set the variable.

def process_request(self, request):
    request.my_var = "whatever"
    return 
like image 151
Rohan Avatar answered Sep 17 '22 13:09

Rohan


If you're setting it on the request, I can't see any reason at all to try and use threadlocals here. You should use the context processor as you describe.

The reason for your problem, though, is that process_response is run in the response phase of the request/response cycle: ie, after your view has been called. You should define process_request instead. See here for a description of the order that middleware methods are called.

like image 24
Daniel Roseman Avatar answered Sep 21 '22 13:09

Daniel Roseman