在模板中设置要在中间件中访问的变量

时间:2013-03-26 09:54:14

标签: django

我似乎很难在我的一个中间件类中设置一个变量,然后我可以在模板层中访问它。

基本布局如下:

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

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

然后在我的模板上找到不同的视图:

{% custom_tag arg_a %}

哪个是应该从请求中返回变量的模板标记:

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

在渲染时出现“Caught AttributeError”错误:'WSGIRequest'对象没有属性'my_var'“

我认为这可能是我在模板标记中访问请求的方式。所以我在This question中将django.core.context_processors.request添加到我的TEMPLATE_CONTEXT_PROCESSORS并尝试将请求对象传递给标记,然后直接从模板访问请求但没有运气。

我认为我对请求对象的工作方式缺乏了解。是否可以将一个变量分配给一个请求对象并在几个视图中选择该变量?我认为请求对象是通过视图传递的,但似乎生成了一个新实例。

如果是这种情况,您将如何在中间件中存储全局变量,然后您可以从应用中的任何位置访问它,无论是在视图还是模板中?

更新

清除混乱(无论是我的还是其他人,我不确定!)我尝试在视图的process_response中间件中设置请求变量,然后在同一视图的模板 。我理解这不起作用,因为在保存变量之前已经处理了模板。 (这是我的故意行为)。

我有两个视图, view1 view2 视图有一个装饰器,它使中间件在请求中设置变量。它是view2模板,它在设置变量之后,我希望访问变量。

2 个答案:

答案 0 :(得分:8)

您尝试在处理中间件的响应期间设置变量。

我认为你应该实现process_request()而不是设置变量。

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

答案 1 :(得分:3)

如果您在请求中设置它,我看不出任何理由尝试在这里使用threadlocals。您应该按照描述使用上下文处理器。

然而,问题的原因是process_response在请求/响应周期的响应阶段运行:即在调用视图之后。您应该定义process_request。有关中间件方法调用顺序的说明,请参阅here