我想你在看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)
正如您在上面看到的,它使用make_context 定义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 从设置中调用处理器并将其绑定到上下文。
Here,您可以查看完整的RequestContext代码。
希望对你有帮助。