什么是Django上下文处理器?

时间:2018-05-10 07:04:55

标签: django

我正在努力解决这些问题。例如,我有这个视图功能

def post_detail(request, year, month, day, post):
    post = get_object_or_404(Post, slug=post,status='published',p__year=year,p__month=month,p__day=day,status='published',)
    return render(request,'blog/post/detail.html',{'post': post})

据我所知,函数将请求对象作为参数,模板路径和变量来呈现给定模板。到现在为止还可以。但现在模板上下文处理器和场景背后的魔力。来自djangoproject

  

TEMPLATE_CONTEXT_PROCESSORS设置是一个可调用的元组 -   称为上下文处理器 - 将请求对象作为它们   参数并返回要合并到的项目字典   上下文

他们到底在做什么?他们会在模板中公开数据,对输入数据有任何限制吗?

2 个答案:

答案 0 :(得分:3)

我认为你在看context_processors是如何运作的,对吧?

你可以看到django源代码 - 它非常棒且组织得很好。

这是跟踪源代码的最佳方式,但我尝试解释一下。

首先,如果您对几乎每个视图使用render(或者render_to_response)。 (甚至在CBV中)。

它返回HttpResponse内容 - 使用loader.render_to_string。为了便于理解,我附上render_to_response

def render_to_response(template_name, context=None, content_type=None, status=None, using=None):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, using=using)
    return HttpResponse(content, content_type, status)

然后你可以找到loader.render_to_string context。它返回template.render(context, request)

class Template(object):

    def __init__(self, template, backend):
        self.template = template
        self.backend = backend

    @property
    def origin(self):
        return self.template.origin

    def render(self, context=None, request=None):
        context = make_context(context, request, autoescape=self.backend.engine.autoescape)
        try:
            return self.template.render(context)
        except TemplateDoesNotExist as exc:
            reraise(exc, self.backend)

如上所述,它使用context定义make_context。在那里,django会自动添加您在settings.py中定义的一些上下文。

def make_context(context, request=None, **kwargs):
    """
    Create a suitable Context from a plain dict and optionally an HttpRequest.
    """
    if context is not None and not isinstance(context, dict):
        raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
    if request is None:
        context = Context(context, **kwargs)
    else:
        # The following pattern is required to ensure values from
        # context override those from template context processors.
        original_context = context
        context = RequestContext(request, **kwargs)
        if original_context:
            context.push(original_context)
    return context

它使用RequestContext从设置调用处理器并将其绑定到上下文。

{{3}},您可以查看完整的RequestContext代码。

我希望它可以帮到你。

答案 1 :(得分:0)

对于每个django视图,无论是基于函数的视图还是基于类的视图,您将在渲染html时返回上下文,如上所述。如果你想要的只是一个简单的页面,其中有一些数据可以显示它的全部。但如果您希望在每个页面上获取某些特定数据,请假设用户详细信息或菜单等,那么很难在您编写的每个视图中插入此数据。这就是为什么你有上下文处理器,你可以编写一个简单的类/函数,它返回一个应该与每个视图的上下文合并的字典。现在您的菜单和用户数据将无缝呈现