中间件与上下文处理器,用于视图相关的导航/显示

时间:2009-08-14 16:53:20

标签: django

这是与middleware and views communicating

上的此SO主题非常相似的问题

我们希望为模板提供一组标准的上下文变量。因此,上下文处理器似乎是合适的,但是,上下文处理器似乎不是视图感知的。我们之前被迫检查调用堆栈以获取有关视图正在执行什么操作的上下文信息。

这就是我们看到中间件线程以及中间件process_view()签名的地方,它为我们提供了视图句柄。

这似乎更接近我们的需求,但不允许我们修改上下文变量,其他中间件方法也没有。

因此,我们最初的想法是使用我们模板所需的所有全局和上下文信息来修改请求对象,并强制模板从{{request.something}}调用我们需要的特定信息,例如{ {1}}。

所以,我们的问题:

  • 修改/设置请求对象上的值是否可以将上下文/全局应用程序特定信息推送到模板?或者标准做法总是把它放在上下文中?
  • 是否有方法/技巧使上下文处理器视图意识到不涉及明确地传递它或进行一些堆栈内省?
  • {{request.viewname}}是否有机会修改上下文或是不可变的?

2 个答案:

答案 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 {}