这是与middleware and views communicating
上的此SO主题非常相似的问题我们希望为模板提供一组标准的上下文变量。因此,上下文处理器似乎是合适的,但是,上下文处理器似乎不是视图感知的。我们之前被迫检查调用堆栈以获取有关视图正在执行什么操作的上下文信息。
这就是我们看到中间件线程以及中间件process_view()
签名的地方,它为我们提供了视图句柄。
这似乎更接近我们的需求,但不允许我们修改上下文变量,其他中间件方法也没有。
因此,我们最初的想法是使用我们模板所需的所有全局和上下文信息来修改请求对象,并强制模板从{{request.something}}
调用我们需要的特定信息,例如{ {1}}。
所以,我们的问题:
{{request.viewname}}
是否有机会修改上下文或是不可变的?答案 0 :(得分:4)
在中间件中为请求设置变量是完全有效的 - 我会一直这样做。
没有办法使用process_response
,因为那时模板已经被渲染了 - 此时你得到的只是一个包含一堆HTML的HttpResponse
。
另一种方法可能是使用您自己的函数包装render_to_response
,该函数将上下文与请求和模板一起使用,并在切换到实际的渲染函数之前根据需要修改它。这样做的好处是可以修改实际的上下文,但缺点是你必须记住在每个视图中调用它而不是默认函数。
答案 1 :(得分:2)
您可以通过串联使用中间件和上下文处理器来实现。中间件知道视图,并可以在请求上设置属性。然后,上下文处理器可以将请求中设置的任何内容移动到上下文中。
例如:
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
然后是上下文处理器:
def extra_context(request):
"""Context processor for adding extra context.
Works in tandem with ExtraContextMiddleware."""
try:
return request.extra_context
except AttributeError:
return {}