{"title":"Django 模板语言：对于 Python 开发者","version":"6.1","locale":"zh-hans","docname":"ref/templates/api","url":"/zh-hans/6.1/ref/templates/api/","canonical":"https://djangodocs.dev/zh-hans/6.1/ref/templates/api/","summary":"这篇文档从技术角度解释了 Django 模板系统——它是如何工作的以及如何扩展它。如果你想找语言语法的参考，请看 Django 模板语言。","html":"<h1>Django 模板语言：对于 Python 开发者<a class=\"heading-anchor\" href=\"#the-django-template-language-for-python-programmers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>这篇文档从技术角度解释了 Django 模板系统——它是如何工作的以及如何扩展它。如果你想找语言语法的参考，请看 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/templates/language/\"><span class=\"doc\">Django 模板语言</span></a>。</p>\n<p>它的前提是对模板、上下文、变量、标签和渲染的理解。如果你不熟悉这些概念，可以从 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#template-language-intro\"><span class=\"std std-ref\">Django 模板语言介绍</span></a> 开始。</p>\n<section id=\"overview\">\n<h2>概况<a class=\"heading-anchor\" href=\"#overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>在 Python 中使用模板系统是一个三步走的过程：</p>\n<ol class=\"arabic simple\">\n<li><p>你设置了一个 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a>。</p></li>\n<li><p>你把模板代码编译成一个 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a>。</p></li>\n<li><p>你用一个 <a class=\"reference internal\" href=\"#django.template.Context\" title=\"django.template.Context\"><code class=\"xref py py-class docutils literal notranslate\">Context</code></a> 来渲染模板。</p></li>\n</ol>\n<p>Django 项目一般依靠 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#template-engines\"><span class=\"std std-ref\">高级、后端不可知的 API</span></a> 来完成每一个步骤，而不是模板系统的低级 API。</p>\n<ol class=\"arabic simple\">\n<li><p>对于 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> 设置中的每一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 后端，Django 都会实例化一个 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a>。 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 封装 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a> 并将其适配到通用的模板后端 API 中。</p></li>\n<li><p><a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#module-django.template.loader\" title=\"django.template.loader\"><code class=\"xref py py-mod docutils literal notranslate\">django.template.loader</code></a> 模块提供了 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.loader.get_template\" title=\"django.template.loader.get_template\"><code class=\"xref py py-func docutils literal notranslate\">get_template()</code></a> 等函数来加载模板。它们返回一个 <code class=\"docutils literal notranslate\">django.template.backends.django.Template</code>，它封装了实际的 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#module-django.template\" title=\"django.template: Django's template system\"><code class=\"xref py py-class docutils literal notranslate\">django.template</code></a>。</p></li>\n<li><p>上一步得到的 <code class=\"docutils literal notranslate\">Template</code> 有一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.base.Template.render\" title=\"django.template.backends.base.Template.render\"><code class=\"xref py py-meth docutils literal notranslate\">render()</code></a> 方法，它将一个上下文和可能的请求汇集到一个 <a class=\"reference internal\" href=\"#django.template.Context\" title=\"django.template.Context\"><code class=\"xref py py-class docutils literal notranslate\">Context</code></a> 中，并委托底层的 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a> 进行渲染。</p></li>\n</ol>\n</section>\n<section id=\"configuring-an-engine\">\n<h2>设置引擎<a class=\"heading-anchor\" href=\"#configuring-an-engine\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>如果你使用的是 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 后端，这可能不是你要找的文档。下面描述的 <code class=\"docutils literal notranslate\">Engine</code> 类的实例可以通过该后端的 <code class=\"docutils literal notranslate\">engine</code> 属性来访问，下面提到的任何属性默认值都会被 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 传递的内容所覆盖。</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.Engine\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Engine</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">dirs<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">app_dirs<span class=\"o\">=</span><span class=\"default_value\">False</span></em>, <em class=\"sig-param\">context_processors<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">debug<span class=\"o\">=</span><span class=\"default_value\">False</span></em>, <em class=\"sig-param\">loaders<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">string_if_invalid<span class=\"o\">=</span><span class=\"default_value\">''</span></em>, <em class=\"sig-param\">file_charset<span class=\"o\">=</span><span class=\"default_value\">'utf-8'</span></em>, <em class=\"sig-param\">libraries<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">builtins<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">autoescape<span class=\"o\">=</span><span class=\"default_value\">True</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Engine\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>当实例化一个 <code class=\"docutils literal notranslate\">Engine</code> 时，所有的参数都必须作为关键字参数传递。</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\">dirs</code> 是引擎应该寻找模板源文件的目录列表。它用于配置 <a class=\"reference internal\" href=\"#django.template.loaders.filesystem.Loader\" title=\"django.template.loaders.filesystem.Loader\"><code class=\"xref py py-class docutils literal notranslate\">filesystem.Loader</code></a>。</p>\n<p>默认为空列表。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">app_dirs</code> 只影响 <code class=\"docutils literal notranslate\">loaders</code> 的默认值。见下文。</p>\n<p>默认为 <code class=\"docutils literal notranslate\">False</code>。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">autoescape</code> 控制是否启用 HTML 自动转码。</p>\n<p>默认为 <code class=\"docutils literal notranslate\">True</code>。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>只有当你渲染非 HTML 模板时，才将其设置为 <code class=\"docutils literal notranslate\">False</code>！</p>\n</aside>\n</li>\n<li><p><code class=\"docutils literal notranslate\">context_processors</code> 是一个点分隔 Python 路径的列表，当一个模板被请求渲染时，这些可调用对象被用来填充上下文。这些可调用对象以一个请求对象作为参数，并返回一个 <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#dict\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\">dict</code></a> 的项目，这些项目将被合并到上下文中。</p>\n<p>默认为空列表。</p>\n<p>查看 <a class=\"reference internal\" href=\"#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\">RequestContext</code></a> 获取更多信息。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">debug</code> 是一个开启／关闭模板调试模式的布尔值。如果它为 <code class=\"docutils literal notranslate\">True</code>，模板引擎将存储额外的调试信息，这些信息可用于显示模板渲染过程中出现的任何异常的详细报告。</p>\n<p>默认为 <code class=\"docutils literal notranslate\">False</code>。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">loaders</code> 是一个模板加载器类的列表，以字符串形式指定。每个 <code class=\"docutils literal notranslate\">Loader</code> 类都知道如何从特定来源导入模板。可以选择使用元组来代替字符串。元组中的第一项应该是 <code class=\"docutils literal notranslate\">Loader</code> 类名，随后的项目在初始化时传递给 <code class=\"docutils literal notranslate\">Loader</code>。</p>\n<p>它默认为包含以下内容的列表：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">'django.template.loaders.filesystem.Loader'</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">'django.template.loaders.app_directories.Loader'</code> 如果且仅当 <code class=\"docutils literal notranslate\">app_dirs</code> 为 <code class=\"docutils literal notranslate\">True</code> 时。</p></li>\n</ul>\n<p>然后，这些加载器会被包装在 <a class=\"reference internal\" href=\"#django.template.loaders.cached.Loader\" title=\"django.template.loaders.cached.Loader\"><code class=\"xref py py-class docutils literal notranslate\">django.template.loaders.cached.Loader</code></a> 中。</p>\n<p>查看 <a class=\"reference internal\" href=\"#template-loaders\"><span class=\"std std-ref\">加载器类型</span></a> 获取详细信息。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">string_if_invalid</code> 是模板系统对无效变量（如拼写错误）应使用的字符串输出。</p>\n<p>默认为空字符串。</p>\n<p>查看 <a class=\"reference internal\" href=\"#invalid-template-variables\"><span class=\"std std-ref\">如何处理无效变量</span></a> 获取更多信息。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">file_charset</code> 是用来读取磁盘上模板文件的字符集。</p>\n<p>默认为 <code class=\"docutils literal notranslate\">'utf-8'</code>。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">'libraries'</code>：模板标签模块的标签和点分隔 Python 路径字典，用于向模板引擎注册。它用于添加新库或为现有库提供替代标签。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Engine<span class=\"p\">(</span>\n    libraries<span class=\"o\">=</span><span class=\"p\">{</span>\n        <span class=\"s2\">&quot;myapp_tags&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;path.to.myapp.tags&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;admin.urls&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.contrib.admin.templatetags.admin_urls&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>可以通过将相应的字典键传递到 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\">{% load %}</code></a> 标签来加载库。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">'builtins'</code>：要添加的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/templates/builtins/\"><span class=\"doc\">内置模板标签和过滤器</span></a> 的点分隔 Python 路径列表。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>Engine<span class=\"p\">(</span>\n    builtins<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;myapp.builtins&quot;</span><span class=\"p\">],</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>可以使用内置库中的标签和过滤器，而不需要先调用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\">{% load %}</code></a> 标签。</p>\n</li>\n</ul>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Engine.get_default\">\n<em class=\"property\"><span class=\"k\">static</span> </em><span class=\"sig-prename descclassname\">Engine.</span><span class=\"sig-name descname\">get_default</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Engine.get_default\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>从第一个配置的 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 引擎中返回底层 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a>。如果没有配置引擎，则引发 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/exceptions/#django.core.exceptions.ImproperlyConfigured\" title=\"django.core.exceptions.ImproperlyConfigured\"><code class=\"xref py py-exc docutils literal notranslate\">ImproperlyConfigured</code></a>。</p>\n<p>这是为保存依赖于全局可用、隐式配置引擎的 API 所必需的。任何其他用途都是不鼓励的。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Engine.from_string\">\n<span class=\"sig-prename descclassname\">Engine.</span><span class=\"sig-name descname\">from_string</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">template_code</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Engine.from_string\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>编译给定的模板代码并返回一个 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a> 对象。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Engine.get_template\">\n<span class=\"sig-prename descclassname\">Engine.</span><span class=\"sig-name descname\">get_template</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">template_name</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Engine.get_template\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>加载给定名称的模板，编译后返回一个 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a> 对象。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Engine.select_template\">\n<span class=\"sig-prename descclassname\">Engine.</span><span class=\"sig-name descname\">select_template</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">template_name_list</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Engine.select_template\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>就像 <a class=\"reference internal\" href=\"#django.template.Engine.get_template\" title=\"django.template.Engine.get_template\"><code class=\"xref py py-meth docutils literal notranslate\">get_template()</code></a> 一样，只不过它接收一个名称列表，并返回找到的第一个模板。</p>\n</dd></dl>\n\n</section>\n<section id=\"loading-a-template\">\n<h2>加载模板<a class=\"heading-anchor\" href=\"#loading-a-template\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>推荐的创建 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a> 的方法是调用 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a> 的工厂方法： <a class=\"reference internal\" href=\"#django.template.Engine.get_template\" title=\"django.template.Engine.get_template\"><code class=\"xref py py-meth docutils literal notranslate\">get_template()</code></a>、 <a class=\"reference internal\" href=\"#django.template.Engine.select_template\" title=\"django.template.Engine.select_template\"><code class=\"xref py py-meth docutils literal notranslate\">select_template()</code></a> 和 <a class=\"reference internal\" href=\"#django.template.Engine.from_string\" title=\"django.template.Engine.from_string\"><code class=\"xref py py-meth docutils literal notranslate\">from_string()</code></a>。</p>\n<p>在 Django 项目中，如果 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> 设置定义了一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 引擎，那么可以直接实例化一个 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a>。如果定义了多个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\">DjangoTemplates</code></a> 引擎，则使用第一个引擎。</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.Template\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Template</span><a class=\"heading-anchor\" href=\"#django.template.Template\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>这个类位于 <code class=\"docutils literal notranslate\">django.template.Template</code>。构造函数需要一个参数——原始模板代码：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> Template\n\ntemplate <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;My name is {{ my_name }}.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</dd></dl>\n\n<aside class=\"admonition-behind-the-scenes admonition\" role=\"note\">\n<p class=\"admonition-title\">幕后</p>\n<p>系统只在创建 <code class=\"docutils literal notranslate\">Template</code> 对象时解析一次原始模板代码。从那时起，为了提高性能，它将以树结构的形式存储在内部。</p>\n<p>即使是解析本身也是相当快的。大部分的解析工作都是通过调用一个简短的正则表达式来完成的。</p>\n</aside>\n</section>\n<section id=\"rendering-a-context\">\n<h2>渲染上下文<a class=\"heading-anchor\" href=\"#rendering-a-context\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>一旦你有一个编译过的 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a> 对象，你就可以用它来渲染一个上下文。你可以重复使用同一个模板，在不同的上下文中多次渲染它。</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Context</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">dict_<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">autoescape<span class=\"o\">=</span><span class=\"default_value\">True</span></em>, <em class=\"sig-param\">use_l10n<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">use_tz<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><code class=\"docutils literal notranslate\">django.template.Context</code> 的构造函数需要一个可选的参数——一个将变量名映射到变量值的字典。</p>\n<p>还可以指定三个可选的关键字参数：</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\">autoescape</code> 控制是否启用 HTML 自动转码。</p>\n<p>默认为 <code class=\"docutils literal notranslate\">True</code>。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>只有当你渲染非 HTML 模板时，才将其设置为 <code class=\"docutils literal notranslate\">False</code>！</p>\n</aside>\n</li>\n<li><p><code class=\"docutils literal notranslate\">use_l10n</code> 覆盖值是否默认本地化。如果设置为 <code class=\"docutils literal notranslate\">True</code>，数字和日期将根据区域设置格式化。</p>\n<p>它默认为 <code class=\"docutils literal notranslate\">None</code>。</p>\n<p>有关详细信息，请参阅 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/i18n/formatting/#topic-l10n-templates\"><span class=\"std std-ref\">在模板中控制本地化</span></a>。</p>\n</li>\n<li><p><code class=\"docutils literal notranslate\">use_tz</code> 覆盖日期在模板中渲染时是否转换为本地时间。如果设置为 <code class=\"docutils literal notranslate\">True</code>，所有日期将使用本地时区渲染。这优先于 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-USE_TZ\"><code class=\"xref std std-setting docutils literal notranslate\">USE_TZ</code></a>。</p>\n<p>它默认为 <code class=\"docutils literal notranslate\">None</code>。</p>\n<p>有关详细信息，请参阅 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/i18n/timezones/#time-zones-in-templates\"><span class=\"std std-ref\">模板中的有时区输出</span></a>。</p>\n</li>\n</ul>\n<p>例如用法，请参阅下面的 <a class=\"reference internal\" href=\"#playing-with-context\"><span class=\"std std-ref\">使用 Context 对象</span></a>。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Template.render\">\n<span class=\"sig-prename descclassname\">Template.</span><span class=\"sig-name descname\">render</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">context</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Template.render\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>使用一个 <a class=\"reference internal\" href=\"#django.template.Context\" title=\"django.template.Context\"><code class=\"xref py py-class docutils literal notranslate\">Context</code></a> 调用 <a class=\"reference internal\" href=\"#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\">Template</code></a> 对象的 <code class=\"docutils literal notranslate\">render()</code> 方法来&quot;填充&quot;模板：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> Context<span class=\"p\">,</span> Template\n<span class=\"gp\">&gt;&gt;&gt; </span>template <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;My name is {{ my_name }}.&quot;</span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span>context <span class=\"o\">=</span> Context<span class=\"p\">({</span><span class=\"s2\">&quot;my_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Adrian&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>template<span class=\"o\">.</span>render<span class=\"p\">(</span>context<span class=\"p\">)</span>\n<span class=\"go\">&quot;My name is Adrian.&quot;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span>context <span class=\"o\">=</span> Context<span class=\"p\">({</span><span class=\"s2\">&quot;my_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Dolores&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>template<span class=\"o\">.</span>render<span class=\"p\">(</span>context<span class=\"p\">)</span>\n<span class=\"go\">&quot;My name is Dolores.&quot;</span>\n</code></pre></div>\n</dd></dl>\n\n<section id=\"variables-and-lookups\">\n<h3>变量和查找<a class=\"heading-anchor\" href=\"#variables-and-lookups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>变量名称必须由任何字母（A-Z）、任何数字（0-9）、下划线（但不得以下划线开头）或点组成。</p>\n<p>点在模板渲染中具有特殊的意义。变量名中的点表示 <strong>查找</strong>。具体来说，当模板系统遇到变量名中的点时，它将按照以下顺序尝试进行查找：</p>\n<ul class=\"simple\">\n<li><p>词典查找。例如：<code class=\"docutils literal notranslate\">foo[&quot;bar&quot;]</code></p></li>\n<li><p>属性查找。例如：<code class=\"docutils literal notranslate\">foo.bar</code></p></li>\n<li><p>列表索引查找。例如：<code class=\"docutils literal notranslate\">foo[bar]</code></p></li>\n</ul>\n<p>请注意，像 <code class=\"docutils literal notranslate\">{{ foo.bar }}</code> 这样的模板表达式中的“bar”将被解释为一个字面字符串，而不是使用变量“bar”的值，如果模板上下文中存在的话。</p>\n<p>模板系统使用第一个有效的查找类型。它是短路逻辑。以下是一些示例：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> Context<span class=\"p\">,</span> Template\n<span class=\"gp\">&gt;&gt;&gt; </span>t <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;My name is {{ person.first_name }}.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>d <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;person&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;first_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Joe&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Johnson&quot;</span><span class=\"p\">}}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t<span class=\"o\">.</span>render<span class=\"p\">(</span>Context<span class=\"p\">(</span>d<span class=\"p\">))</span>\n<span class=\"go\">&quot;My name is Joe.&quot;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span> <span class=\"nc\">PersonClass</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"k\">pass</span>\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p <span class=\"o\">=</span> PersonClass<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p<span class=\"o\">.</span>first_name <span class=\"o\">=</span> <span class=\"s2\">&quot;Ron&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p<span class=\"o\">.</span>last_name <span class=\"o\">=</span> <span class=\"s2\">&quot;Nasty&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t<span class=\"o\">.</span>render<span class=\"p\">(</span>Context<span class=\"p\">({</span><span class=\"s2\">&quot;person&quot;</span><span class=\"p\">:</span> p<span class=\"p\">}))</span>\n<span class=\"go\">&quot;My name is Ron.&quot;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span>t <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;The first stooge in the list is {{ stooges.0 }}.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">({</span><span class=\"s2\">&quot;stooges&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;Larry&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Curly&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Moe&quot;</span><span class=\"p\">]})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t<span class=\"o\">.</span>render<span class=\"p\">(</span>c<span class=\"p\">)</span>\n<span class=\"go\">&quot;The first stooge in the list is Larry.&quot;</span>\n</code></pre></div>\n<p>如果变量的任何部分都是可调用的，模板系统将尝试调用它。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span> <span class=\"nc\">PersonClass2</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span> <span class=\"nf\">name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">return</span> <span class=\"s2\">&quot;Samantha&quot;</span>\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;My name is {{ person.name }}.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t<span class=\"o\">.</span>render<span class=\"p\">(</span>Context<span class=\"p\">({</span><span class=\"s2\">&quot;person&quot;</span><span class=\"p\">:</span> PersonClass2<span class=\"p\">}))</span>\n<span class=\"go\">&quot;My name is Samantha.&quot;</span>\n</code></pre></div>\n<p>可调用对象的变量比只需要直接查找的变量要复杂一些。下面是一些需要注意的事项：</p>\n<ul>\n<li><p>如果在调用变量时引发异常，除非异常具有一个名为 <code class=\"docutils literal notranslate\">silent_variable_failure</code> 的属性且其值为 <code class=\"docutils literal notranslate\">True</code>，否则异常将被传播。如果异常确实具有值为 <code class=\"docutils literal notranslate\">True</code> 的 <code class=\"docutils literal notranslate\">silent_variable_failure</code> 属性，则变量将呈现为引擎的 <code class=\"docutils literal notranslate\">string_if_invalid</code> 配置选项的值（默认为空字符串）。例如：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>t <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;My name is {{ person.first_name }}.&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span> <span class=\"nc\">PersonClass3</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span> <span class=\"nf\">first_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">raise</span> <span class=\"ne\">AssertionError</span><span class=\"p\">(</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p <span class=\"o\">=</span> PersonClass3<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t<span class=\"o\">.</span>render<span class=\"p\">(</span>Context<span class=\"p\">({</span><span class=\"s2\">&quot;person&quot;</span><span class=\"p\">:</span> p<span class=\"p\">}))</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">AssertionError</span>: foo\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span> <span class=\"nc\">SilentAssertionError</span><span class=\"p\">(</span><span class=\"ne\">Exception</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    silent_variable_failure <span class=\"o\">=</span> <span class=\"kc\">True</span>\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">class</span> <span class=\"nc\">PersonClass4</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"k\">def</span> <span class=\"nf\">first_name</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>        <span class=\"k\">raise</span> SilentAssertionError\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>p <span class=\"o\">=</span> PersonClass4<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>t<span class=\"o\">.</span>render<span class=\"p\">(</span>Context<span class=\"p\">({</span><span class=\"s2\">&quot;person&quot;</span><span class=\"p\">:</span> p<span class=\"p\">}))</span>\n<span class=\"go\">&quot;My name is .&quot;</span>\n</code></pre></div>\n<p>请注意 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/exceptions/#django.core.exceptions.ObjectDoesNotExist\" title=\"django.core.exceptions.ObjectDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\">django.core.exceptions.ObjectDoesNotExist</code></a> 是所有 Django 数据库 API <code class=\"docutils literal notranslate\">DoesNotExist</code> 异常的基类，有 <code class=\"docutils literal notranslate\">silent_variable_failure = True</code>。所以如果你使用 Django 模板与 Django 模型对象，任何 <code class=\"docutils literal notranslate\">DoesNotExist</code> 异常都会静默失败。</p>\n</li>\n<li><p>一个变量只有在没有所需参数的情况下才可以被调用，否则，系统将返回引擎的 <code class=\"docutils literal notranslate\">string_if_invalid</code> 选项的值。否则，系统将返回引擎的 <code class=\"docutils literal notranslate\">string_if_invalid</code> 选项的值。</p></li>\n</ul>\n<ul id=\"alters-data-description\">\n<li><p>在调用一些变量的时候可能会有副作用，如果让模板系统访问这些变量，要么是傻瓜，要么是安全漏洞。</p>\n<p>一个很好的例子是每个 Django 模型对象上的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a> 方法。模板系统不应该允许执行这样的操作：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code>I will now delete this valuable data. <span class=\"cp\">{{</span> <span class=\"nv\">data.delete</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>To prevent this, set an <code class=\"docutils literal notranslate\">alters_data</code> attribute on the callable\nvariable. The template system won't call a variable if it has\n<code class=\"docutils literal notranslate\">alters_data=True</code> set, and will instead replace the variable with\n<code class=\"docutils literal notranslate\">string_if_invalid</code>, unconditionally. The\ndynamically-generated <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\">delete()</code></a> and\n<a class=\"reference internal\" href=\"/zh-hans/6.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> methods on Django model objects get\n<code class=\"docutils literal notranslate\">alters_data=True</code> automatically. Example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span> <span class=\"nf\">sensitive_function</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span>database_record<span class=\"o\">.</span>delete<span class=\"p\">()</span>\n\n\nsensitive_function<span class=\"o\">.</span>alters_data <span class=\"o\">=</span> <span class=\"kc\">True</span>\n</code></pre></div>\n</li>\n<li><p>Occasionally you may want to turn off this feature for other reasons,\nand tell the template system to leave a variable uncalled no matter\nwhat. To do so, set a <code class=\"docutils literal notranslate\">do_not_call_in_templates</code> attribute on the\ncallable with the value <code class=\"docutils literal notranslate\">True</code>. The template system then will act as\nif your variable is not callable (allowing you to access attributes of\nthe callable, for example).</p></li>\n</ul>\n</section>\n<section id=\"how-invalid-variables-are-handled\">\n<span id=\"invalid-template-variables\"></span><h3>如何处理无效变量<a class=\"heading-anchor\" href=\"#how-invalid-variables-are-handled\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>一般来说，如果一个变量不存在，模板系统会插入引擎的 <code class=\"docutils literal notranslate\">string_if_invalid</code> 配置选项的值，默认设置为 <code class=\"docutils literal notranslate\">''</code> （空字符串）。</p>\n<p>只有当 <code class=\"docutils literal notranslate\">string_if_invalid</code> 被设置为 <code class=\"docutils literal notranslate\">''</code> （空字符串）时，才会对无效变量应用过滤器。如果 <code class=\"docutils literal notranslate\">string_if_invalid</code> 被设置为任何其他值，变量过滤器将被忽略。</p>\n<p>对于 <code class=\"docutils literal notranslate\">if</code>、<code class=\"docutils literal notranslate\">for</code> 和 <code class=\"docutils literal notranslate\">regroup</code> 模板标签，这种行为略有不同。如果向这些模板标签之一提供了一个无效的变量，该变量将被解释为 <code class=\"docutils literal notranslate\">None</code>。过滤器总是应用于这些模板标签中的无效变量。</p>\n<p>如果 <code class=\"docutils literal notranslate\">string_if_invalid</code> 包含 <code class=\"docutils literal notranslate\">'%s'</code>，格式标记将被替换为无效变量的名称。</p>\n<aside class=\"admonition-for-debug-purposes-only admonition\" role=\"note\">\n<p class=\"admonition-title\">仅供调试使用！</p>\n<p>虽然 <code class=\"docutils literal notranslate\">string_if_invalid</code> 是一个有用的调试工具，但把它作为“开发默认值”是一个坏主意。</p>\n<p>很多模板，包括一些 Django 的模板，在遇到不存在的变量时，都会依靠模板系统的静默。如果你给 <code class=\"docutils literal notranslate\">''</code>  <code class=\"docutils literal notranslate\">string_if_invalid</code> 以外的值，你会在这些模板和网站上遇到渲染问题。</p>\n<p>一般来说，<code class=\"docutils literal notranslate\">string_if_invalid</code> 只有在调试某个特定的模板问题时才应该启用，调试完成后再清除。</p>\n</aside>\n</section>\n<section id=\"built-in-variables\">\n<h3>内置变量<a class=\"heading-anchor\" href=\"#built-in-variables\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>每个上下文都包含 <code class=\"docutils literal notranslate\">True</code>、<code class=\"docutils literal notranslate\">False</code> 和 <code class=\"docutils literal notranslate\">None</code>。正如你所期望的那样，这些变量解析为相应的 Python 对象。</p>\n</section>\n<section id=\"limitations-with-string-literals\">\n<h3>字符串的限制<a class=\"heading-anchor\" href=\"#limitations-with-string-literals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 的模板语言没有办法转义用于自己语法的字符。例如，如果你需要输出像 <code class=\"docutils literal notranslate\">{%</code> 和 <code class=\"docutils literal notranslate\">%}</code> 这样的字符序列，就需要使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/templates/builtins/#std-templatetag-templatetag\"><code class=\"xref std std-ttag docutils literal notranslate\">templatetag</code></a> 标签。</p>\n<p>如果您想在模板过滤器或标签参数中包含这些序列，也会存在类似的问题。例如，在解析块标签时，Django 的模板解析器会查找在 <code class=\"docutils literal notranslate\">{%</code> 之后第一次出现的 <code class=\"docutils literal notranslate\">%}</code>。这会阻止使用 <code class=\"docutils literal notranslate\">&quot;%}&quot;</code> 作为字符串文字。例如，以下表达式将引发 <code class=\"docutils literal notranslate\">TemplateSyntaxError</code>：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">include</span> <span class=\"s2\">&quot;template.html&quot;</span> <span class=\"nv\">tvar</span><span class=\"o\">=</span><span class=\"s2\">&quot;Some string literal with %} in it.&quot;</span> <span class=\"cp\">%}</span>\n\n<span class=\"cp\">{%</span> <span class=\"k\">with</span> <span class=\"nv\">tvar</span><span class=\"o\">=</span><span class=\"s2\">&quot;Some string literal with %} in it.&quot;</span> <span class=\"cp\">%}{%</span> <span class=\"k\">endwith</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>在过滤器参数中使用保留序列也可能触发相同的问题：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">some.variable</span><span class=\"o\">|</span><span class=\"nf\">default</span><span class=\"s2\">:&quot;}}&quot;</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>如果你需要使用这些序列的字符串，请将它们存储在模板变量中，或者使用自定义模板标签或过滤器来解决这个限制。</p>\n</section>\n</section>\n<section id=\"playing-with-context-objects\">\n<span id=\"playing-with-context\"></span><h2>使用 <code class=\"docutils literal notranslate\">Context</code> 对象<a class=\"heading-anchor\" href=\"#playing-with-context-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>大多数情况下，您将通过将完全填充的字典传递给 <code class=\"docutils literal notranslate\">Context()</code> 来实例化 <a class=\"reference internal\" href=\"#django.template.Context\" title=\"django.template.Context\"><code class=\"xref py py-class docutils literal notranslate\">Context</code></a> 对象。但是，一旦实例化了 <code class=\"docutils literal notranslate\">Context</code> 对象，您也可以使用标准字典语法向其中添加和删除项目：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> Context\n<span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">({</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">})</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;bar&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">del</span> c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">KeyError</span>: &#39;foo&#39;\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;newvariable&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;hello&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;newvariable&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;hello&#39;</span>\n</code></pre></div>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context.get\">\n<span class=\"sig-prename descclassname\">Context.</span><span class=\"sig-name descname\">get</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">key</em>, <em class=\"sig-param\">otherwise<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context.get\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>如果 <code class=\"docutils literal notranslate\">key</code> 在上下文中，返回 <code class=\"docutils literal notranslate\">key</code> 的值，否则返回 <code class=\"docutils literal notranslate\">otherwise</code>。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context.setdefault\">\n<span class=\"sig-prename descclassname\">Context.</span><span class=\"sig-name descname\">setdefault</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">key</em>, <em class=\"sig-param\">default<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context.setdefault\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>如果 <code class=\"docutils literal notranslate\">key</code> 在上下文中，则返回其值。否则用 <code class=\"docutils literal notranslate\">default</code> 值插入 <code class=\"docutils literal notranslate\">key</code> 并返回 <code class=\"docutils literal notranslate\">default</code>。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context.pop\">\n<span class=\"sig-prename descclassname\">Context.</span><span class=\"sig-name descname\">pop</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context.pop\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context.push\">\n<span class=\"sig-prename descclassname\">Context.</span><span class=\"sig-name descname\">push</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context.push\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py exception\">\n<dt class=\"sig sig-object py\" id=\"django.template.ContextPopException\">\n<em class=\"property\"><span class=\"k\">exception</span> </em><span class=\"sig-name descname\">ContextPopException</span><a class=\"heading-anchor\" href=\"#django.template.ContextPopException\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\">Context</code> 对象是一个堆栈。也就是说，您可以对其进行 <code class=\"docutils literal notranslate\">push()</code> 和 <code class=\"docutils literal notranslate\">pop()</code> 操作。如果您进行了过多的 <code class=\"docutils literal notranslate\">pop()</code> 操作，它会引发 <code class=\"docutils literal notranslate\">django.template.ContextPopException</code> 异常：</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>push<span class=\"p\">()</span>\n<span class=\"go\">{}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;second level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;second level&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>pop<span class=\"p\">()</span>\n<span class=\"go\">{&#39;foo&#39;: &#39;second level&#39;}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;first level&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;overwritten&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;overwritten&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>pop<span class=\"p\">()</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n<span class=\"c\">...</span>\n<span class=\"gr\">ContextPopException</span>\n</code></pre></div>\n<p>你也可以使用 <code class=\"docutils literal notranslate\">push()</code> 作为上下文管理器，以确保匹配的 <code class=\"docutils literal notranslate\">pop()</code> 被调用。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">with</span> c<span class=\"o\">.</span>push<span class=\"p\">():</span>\n<span class=\"gp\">... </span>    c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;second level&quot;</span>\n<span class=\"gp\">... </span>    c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&#39;second level&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;first level&#39;</span>\n</code></pre></div>\n<p>传递给 <code class=\"docutils literal notranslate\">push()</code> 的所有参数都将传递给 <code class=\"docutils literal notranslate\">dict</code> 构造函数，用于建立新的上下文层次。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">with</span> c<span class=\"o\">.</span>push<span class=\"p\">(</span>foo<span class=\"o\">=</span><span class=\"s2\">&quot;second level&quot;</span><span class=\"p\">):</span>\n<span class=\"gp\">... </span>    c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&#39;second level&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;first level&#39;</span>\n</code></pre></div>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context.update\">\n<span class=\"sig-prename descclassname\">Context.</span><span class=\"sig-name descname\">update</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">other_dict</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context.update\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>除了 <code class=\"docutils literal notranslate\">push()</code> 和 <code class=\"docutils literal notranslate\">pop()</code> 之外，<code class=\"docutils literal notranslate\">Context</code> 对象还定义了一个 <code class=\"docutils literal notranslate\">update()</code> 方法。它的工作原理与 <code class=\"docutils literal notranslate\">push()</code> 类似，但它接受一个字典作为参数，并将该字典推到栈上，而不是空的。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>update<span class=\"p\">({</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;updated&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">{&#39;foo&#39;: &#39;updated&#39;}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;updated&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>pop<span class=\"p\">()</span>\n<span class=\"go\">{&#39;foo&#39;: &#39;updated&#39;}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;first level&#39;</span>\n</code></pre></div>\n<p>像 <code class=\"docutils literal notranslate\">push()</code> 一样，你可以使用 <code class=\"docutils literal notranslate\">update()</code> 作为上下文管理器，以确保调用匹配的 <code class=\"docutils literal notranslate\">pop()</code>。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">with</span> c<span class=\"o\">.</span>update<span class=\"p\">({</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;second level&quot;</span><span class=\"p\">}):</span>\n<span class=\"gp\">... </span>    c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">&#39;second level&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span>\n<span class=\"go\">&#39;first level&#39;</span>\n</code></pre></div>\n<p>在 <a class=\"reference internal\" href=\"/zh-hans/6.1/howto/custom-template-tags/#howto-writing-custom-template-tags\"><span class=\"std std-ref\">一些自定义模板标签</span></a> 中，使用 <code class=\"docutils literal notranslate\">Context</code> 作为栈是很方便的。</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Context.flatten\">\n<span class=\"sig-prename descclassname\">Context.</span><span class=\"sig-name descname\">flatten</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Context.flatten\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>使用 <code class=\"docutils literal notranslate\">flatten()</code> 方法，你可以得到整个 <code class=\"docutils literal notranslate\">Context</code> 堆栈作为一个字典，包括内置的变量。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>update<span class=\"p\">({</span><span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;second level&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">{&#39;bar&#39;: &#39;second level&#39;}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>flatten<span class=\"p\">()</span>\n<span class=\"go\">{&#39;True&#39;: True, &#39;None&#39;: None, &#39;foo&#39;: &#39;first level&#39;, &#39;False&#39;: False, &#39;bar&#39;: &#39;second level&#39;}</span>\n</code></pre></div>\n<p>内部还使用 <code class=\"docutils literal notranslate\">flatten()</code> 方法使 <code class=\"docutils literal notranslate\">Context</code> 对象具有可比性。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span>c1 <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c1<span class=\"p\">[</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;first level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c1<span class=\"p\">[</span><span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;second level&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c2 <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c2<span class=\"o\">.</span>update<span class=\"p\">({</span><span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;second level&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;first level&quot;</span><span class=\"p\">})</span>\n<span class=\"go\">{&#39;foo&#39;: &#39;first level&#39;, &#39;bar&#39;: &#39;second level&#39;}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c1 <span class=\"o\">==</span> c2\n<span class=\"go\">True</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">flatten()</code> 的结果在单元测试中可以用来比较 <code class=\"docutils literal notranslate\">Context</code> 和 <code class=\"docutils literal notranslate\">dict</code>：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">ContextTest</span><span class=\"p\">(</span>unittest<span class=\"o\">.</span>TestCase<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">test_against_dictionary</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        c1 <span class=\"o\">=</span> Context<span class=\"p\">()</span>\n        c1<span class=\"p\">[</span><span class=\"s2\">&quot;update&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;value&quot;</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span>assertEqual<span class=\"p\">(</span>\n            c1<span class=\"o\">.</span>flatten<span class=\"p\">(),</span>\n            <span class=\"p\">{</span>\n                <span class=\"s2\">&quot;True&quot;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">,</span>\n                <span class=\"s2\">&quot;None&quot;</span><span class=\"p\">:</span> <span class=\"kc\">None</span><span class=\"p\">,</span>\n                <span class=\"s2\">&quot;False&quot;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n                <span class=\"s2\">&quot;update&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;value&quot;</span><span class=\"p\">,</span>\n            <span class=\"p\">},</span>\n        <span class=\"p\">)</span>\n</code></pre></div>\n<section id=\"using-requestcontext\">\n<span id=\"subclassing-context-requestcontext\"></span><h3>使用 <code class=\"docutils literal notranslate\">RequestContext</code><a class=\"heading-anchor\" href=\"#using-requestcontext\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.RequestContext\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">RequestContext</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em>, <em class=\"sig-param\">dict_<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">processors<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">use_l10n<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">use_tz<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">autoescape<span class=\"o\">=</span><span class=\"default_value\">True</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.RequestContext\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Django 附带了一个特殊的 <a class=\"reference internal\" href=\"#django.template.Context\" title=\"django.template.Context\"><code class=\"xref py py-class docutils literal notranslate\">Context</code></a> 类，<code class=\"docutils literal notranslate\">django.template.RequestContext</code>，它的行为与普通的 <code class=\"docutils literal notranslate\">django.template.Context</code> 略有不同。第一个区别是它接受一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\">HttpRequest</code></a> 作为其第一个参数。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>c <span class=\"o\">=</span> RequestContext<span class=\"p\">(</span>\n    request<span class=\"p\">,</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>第二个区别是，它根据引擎的 <code class=\"docutils literal notranslate\">context_processors</code> 配置选项，自动给上下文填充一些变量。</p>\n<p><code class=\"docutils literal notranslate\">context_processors</code> 选项是一个可调用的列表——称为 <strong>上下文处理器</strong>——它将一个请求对象作为参数，并返回一个要合并到上下文中的项目字典。在默认生成的配置文件中，默认模板引擎包含以下上下文处理器：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"p\">[</span>\n    <span class=\"s2\">&quot;django.template.context_processors.request&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.contrib.auth.context_processors.auth&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.contrib.messages.context_processors.messages&quot;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>In addition to these, <a class=\"reference internal\" href=\"#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\">RequestContext</code></a> always enables\n<code class=\"docutils literal notranslate\">'django.template.context_processors.csrf'</code>. This is a security related\ncontext processor required by the admin and other contrib apps, and, in case\nof accidental misconfiguration, it is deliberately hardcoded in and cannot be\nturned off in the <code class=\"docutils literal notranslate\">context_processors</code> option.</p>\n<p>每个处理器都是按顺序应用的。这意味着，如果一个处理器向上下文添加了一个变量，而第二个处理器添加了一个同名的变量，第二个处理器将覆盖第一个处理器。下面解释默认的处理器。</p>\n<aside class=\"admonition-when-context-processors-are-applied admonition\" role=\"note\">\n<p class=\"admonition-title\">当应用上下文处理器时</p>\n<p>上下文处理器是应用在上下文数据之上的。这意味着上下文处理器可能会覆盖你提供给 <a class=\"reference internal\" href=\"#django.template.Context\" title=\"django.template.Context\"><code class=\"xref py py-class docutils literal notranslate\">Context</code></a> 或 <a class=\"reference internal\" href=\"#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\">RequestContext</code></a> 的变量，所以要注意避免变量名与上下文处理器提供的变量名重叠。</p>\n<p>如果你想让上下文数据优先于上下文处理器，请使用以下模式：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> RequestContext\n\nrequest_context <span class=\"o\">=</span> RequestContext<span class=\"p\">(</span>request<span class=\"p\">)</span>\nrequest_context<span class=\"o\">.</span>push<span class=\"p\">({</span><span class=\"s2\">&quot;my_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Adrian&quot;</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>Django 这样做是为了让上下文数据覆盖 API 中的上下文处理器，如 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/http/shortcuts/#django.shortcuts.render\" title=\"django.shortcuts.render\"><code class=\"xref py py-func docutils literal notranslate\">render()</code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\">TemplateResponse</code></a>。</p>\n</aside>\n<p>此外，你还可以使用可选的第三个位置参数 <code class=\"docutils literal notranslate\">processors</code>，给 <a class=\"reference internal\" href=\"#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\">RequestContext</code></a> 一个额外的处理器列表。在这个例子中， <a class=\"reference internal\" href=\"#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\">RequestContext</code></a> 实例得到一个 <code class=\"docutils literal notranslate\">ip_address</code> 变量：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.http</span> <span class=\"kn\">import</span> HttpResponse\n<span class=\"kn\">from</span> <span class=\"nn\">django.template</span> <span class=\"kn\">import</span> RequestContext<span class=\"p\">,</span> Template\n\n\n<span class=\"k\">def</span> <span class=\"nf\">ip_address_processor</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"p\">{</span><span class=\"s2\">&quot;ip_address&quot;</span><span class=\"p\">:</span> request<span class=\"o\">.</span>META<span class=\"p\">[</span><span class=\"s2\">&quot;REMOTE_ADDR&quot;</span><span class=\"p\">]}</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">client_ip_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    template <span class=\"o\">=</span> Template<span class=\"p\">(</span><span class=\"s2\">&quot;{{ title }}: {{ ip_address }}&quot;</span><span class=\"p\">)</span>\n    context <span class=\"o\">=</span> RequestContext<span class=\"p\">(</span>\n        request<span class=\"p\">,</span>\n        <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;title&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Your IP Address&quot;</span><span class=\"p\">,</span>\n        <span class=\"p\">},</span>\n        <span class=\"p\">[</span>ip_address_processor<span class=\"p\">],</span>\n    <span class=\"p\">)</span>\n    <span class=\"k\">return</span> HttpResponse<span class=\"p\">(</span>template<span class=\"o\">.</span>render<span class=\"p\">(</span>context<span class=\"p\">))</span>\n</code></pre></div>\n</section>\n<section id=\"built-in-template-context-processors\">\n<span id=\"context-processors\"></span><h3>内置模板上下文处理器<a class=\"heading-anchor\" href=\"#built-in-template-context-processors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>下面是每个内置处理器的作用：</p>\n<section id=\"django-contrib-auth-context-processors-auth\">\n<h4><code class=\"docutils literal notranslate\">django.contrib.auth.context_processors.auth</code><a class=\"heading-anchor\" href=\"#django-contrib-auth-context-processors-auth\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.context_processors.auth\">\n<span class=\"sig-name descname\">auth</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.context_processors.auth\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果启用了这个处理器，每一个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含这些变量：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">user</code> —— 代表当前登录用户的 <code class=\"docutils literal notranslate\">auth.User</code> 实例（如果客户端没有登录，则为 <code class=\"docutils literal notranslate\">AnonymousUser</code> 实例）。</p></li>\n<li><p><code class=\"docutils literal notranslate\">perms</code> —— <code class=\"docutils literal notranslate\">django.contrib.uth.context_processors.PermWrapper</code> 的实例，表示当前登录用户拥有的权限。</p></li>\n</ul>\n</section>\n<section id=\"django-template-context-processors-debug\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.debug</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-debug\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.template.context_processors.debug\">\n<span class=\"sig-name descname\">debug</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.context_processors.debug\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果启用了这个处理器，每一个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含这两个变量——但前提是你的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\">DEBUG</code></a> 设置为 <code class=\"docutils literal notranslate\">True</code>，并且请求的 IP 地址（<code class=\"docutils literal notranslate\">request.META['REMOTE_ADDR']</code>）在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INTERNAL_IPS\"><code class=\"xref std std-setting docutils literal notranslate\">INTERNAL_IPS</code></a> 配置中：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">debug</code> —— <code class=\"docutils literal notranslate\">True</code>。你可以在模板中使用它来测试你是否处于 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-DEBUG\"><code class=\"xref std std-setting docutils literal notranslate\">DEBUG</code></a> 模式。</p></li>\n<li><p><code class=\"docutils literal notranslate\">sql_queries</code> —— <code class=\"docutils literal notranslate\">{'sql': ..., 'time': ...}</code> 字典的列表，表示在请求过程中迄今为止发生的每一个 SQL 查询，以及花费的时间。这个列表是按照数据库别名，然后按照查询的顺序排列的。它是在访问时惰性生成的。</p></li>\n</ul>\n</section>\n<section id=\"django-template-context-processors-i18n\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.i18n</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-i18n\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.template.context_processors.i18n\">\n<span class=\"sig-name descname\">i18n</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.context_processors.i18n\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果启用了这个处理器，每一个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含这些变量：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">LANGUAGES</code> —— <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-LANGUAGES\"><code class=\"xref std std-setting docutils literal notranslate\">LANGUAGES</code></a> 配置值。</p></li>\n<li><p><code class=\"docutils literal notranslate\">LANGUAGE_BIDI</code> —— <code class=\"docutils literal notranslate\">True</code> 如果当前语言是从右到左的语言，如希伯来语、阿拉伯语。<code class=\"docutils literal notranslate\">False</code> 如果是从左到右的语言，如英语、法语、德语。</p></li>\n<li><p><code class=\"docutils literal notranslate\">LANGUAGE_CODE</code> —— <code class=\"docutils literal notranslate\">request.LANGUAGE_CODE</code>，如果存在的话。否则，使用 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-LANGUAGE_CODE\"><code class=\"xref std std-setting docutils literal notranslate\">LANGUAGE_CODE</code></a> 配置的值。</p></li>\n</ul>\n<p>请参阅 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/i18n/translation/#i18n-template-tags\"><span class=\"std std-ref\">i18n 模板标签</span></a>，了解产生相同值的模板标签。</p>\n</section>\n<section id=\"django-template-context-processors-media\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.media</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-media\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>如果启用了这个处理器，每一个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含一个变量 <code class=\"docutils literal notranslate\">MEDIA_URL</code>，提供 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-MEDIA_URL\"><code class=\"xref std std-setting docutils literal notranslate\">MEDIA_URL</code></a> 配置的值。</p>\n</section>\n<section id=\"django-template-context-processors-static\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.static</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-static\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.template.context_processors.static\">\n<span class=\"sig-name descname\">static</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.context_processors.static\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果启用了这个处理器，每个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含一个变量 <code class=\"docutils literal notranslate\">STATIC_URL</code>，提供 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-STATIC_URL\"><code class=\"xref std std-setting docutils literal notranslate\">STATIC_URL</code></a> 配置的值。</p>\n</section>\n<section id=\"django-template-context-processors-csrf\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.csrf</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-csrf\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>该处理器添加了 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/templates/builtins/#std-templatetag-csrf_token\"><code class=\"xref std std-ttag docutils literal notranslate\">csrf_token</code></a> 模板标签所需的令牌，以防止 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/csrf/\"><span class=\"doc\">跨站点伪造请求</span></a>。</p>\n<p>This is always enabled by <a class=\"reference internal\" href=\"#django.template.RequestContext\" title=\"django.template.RequestContext\"><code class=\"xref py py-class docutils literal notranslate\">RequestContext</code></a> and cannot\nbe disabled. You do not need to include it within <code class=\"docutils literal notranslate\">context_processors</code>.</p>\n</section>\n<section id=\"django-template-context-processors-csp\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.csp</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-csp\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.template.context_processors.csp\">\n<span class=\"sig-name descname\">csp</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.context_processors.csp\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<aside class=\"version-note version-added\" data-version=\"6.0\" role=\"note\">\n<p class=\"version-note-title\">New in Django 6.0</p></aside>\n<p>If this processor is enabled, every <code class=\"docutils literal notranslate\">RequestContext</code> will contain a variable\n<code class=\"docutils literal notranslate\">csp_nonce</code>, providing a securely generated, request-specific nonce suitable\nfor use under a Content Security Policy. See <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/csp/#csp-nonce\"><span class=\"std std-ref\">CSP nonce usage</span></a>\nfor details.</p>\n</section>\n<section id=\"django-template-context-processors-request\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.request</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>如果启用了这个处理器，每个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含一个变量 <code class=\"docutils literal notranslate\">request</code>，就是当前的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\">HttpRequest</code></a>。</p>\n</section>\n<section id=\"django-template-context-processors-tz\">\n<h4><code class=\"docutils literal notranslate\">django.template.context_processors.tz</code><a class=\"heading-anchor\" href=\"#django-template-context-processors-tz\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.template.context_processors.tz\">\n<span class=\"sig-name descname\">tz</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">request</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.context_processors.tz\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>如果启用了这个处理器，每个 <code class=\"docutils literal notranslate\">RequestContext</code> 将包含一个变量 <code class=\"docutils literal notranslate\">TIME_ZONE</code>，提供当前活动时区的名称。</p>\n</section>\n<section id=\"django-contrib-messages-context-processors-messages\">\n<h4><code class=\"docutils literal notranslate\">django.contrib.messages.context_processors.messages</code><a class=\"heading-anchor\" href=\"#django-contrib-messages-context-processors-messages\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>如果启用了这个处理器，每一个 <code class=\"docutils literal notranslate\">RequestContext</code> 都会包含这两个变量：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">messages</code> —— 通过 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/contrib/messages/\"><span class=\"doc\">消息框架</span></a> 设置的信息列表（字符串）。</p></li>\n<li><p><code class=\"docutils literal notranslate\">DEFAULT_MESSAGE_LEVELS</code> —— 信息级别名称与 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/contrib/messages/#message-level-constants\"><span class=\"std std-ref\">其数值</span></a> 的映射。</p></li>\n</ul>\n</section>\n</section>\n<section id=\"writing-your-own-context-processors\">\n<h3>编写你自己的上下文处理器<a class=\"heading-anchor\" href=\"#writing-your-own-context-processors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>上下文处理器具有简单的接口：它是一个 Python 函数，接受一个参数，即 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\">HttpRequest</code></a> 对象，并返回一个添加到模板上下文的字典。</p>\n<p>例如，要将 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-DEFAULT_FROM_EMAIL\"><code class=\"xref std std-setting docutils literal notranslate\">DEFAULT_FROM_EMAIL</code></a> 设置添加到每个上下文中：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.conf</span> <span class=\"kn\">import</span> settings\n\n\n<span class=\"k\">def</span> <span class=\"nf\">from_email</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;DEFAULT_FROM_EMAIL&quot;</span><span class=\"p\">:</span> settings<span class=\"o\">.</span>DEFAULT_FROM_EMAIL<span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n</code></pre></div>\n<p>自定义上下文处理器可以存在于你的代码库中的任何地方。Django 只关心你的自定义上下文处理器是否被你的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> 配置中的 <code class=\"docutils literal notranslate\">'context_processors'</code> 选项所指向，如果你直接使用的话，则是 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a> 的 <code class=\"docutils literal notranslate\">context_processors</code> 参数。</p>\n</section>\n</section>\n<section id=\"loading-templates\">\n<h2>加载模板<a class=\"heading-anchor\" href=\"#loading-templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>一般来说，你会把模板存储在文件系统的文件中，而不是自己使用低级的 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#module-django.template\" title=\"django.template: Django's template system\"><code class=\"xref py py-class docutils literal notranslate\">template</code></a> API。将模板保存在指定的 <strong>template 目录</strong> 中。</p>\n<p>Django 会在很多地方搜索模板目录，这取决于你的模板加载设置（见下面的“加载器类型”），但最基本的指定模板目录的方法是使用 <code class=\"xref std std-setting docutils literal notranslate\">DIRS</code> 选项。</p>\n<section id=\"the-dirs-option\">\n<h3><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> 选项<a class=\"heading-anchor\" href=\"#the-dirs-option\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>通过使用配置文件中的 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> 配置中的 <code class=\"xref std std-setting docutils literal notranslate\">DIRS</code> 选项来告诉 Django 你的模板目录是什么，或者使用 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a> 中的 <code class=\"docutils literal notranslate\">dirs</code> 参数。这应该被设置为一个字符串列表，其中包含你的模板目录的完整路径：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;DIRS&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n            <span class=\"s2\">&quot;/home/html/templates/lawrence.com&quot;</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;/home/html/templates/default&quot;</span><span class=\"p\">,</span>\n        <span class=\"p\">],</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>您的模板可以放在任何地方，只要目录和模板对于 Web 服务器是可读的。它们可以具有任何您想要的扩展名，例如 <code class=\"docutils literal notranslate\">.html</code> 或 <code class=\"docutils literal notranslate\">.txt</code>，或者甚至可以没有扩展名。</p>\n<p>请注意，这些路径应该使用 Unix 风格的斜线，即使在 Windows 上也是如此。</p>\n</section>\n<section id=\"loader-types\">\n<span id=\"template-loaders\"></span><h3>加载器类型<a class=\"heading-anchor\" href=\"#loader-types\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>默认情况下，Django 使用的是基于文件系统的模板加载器，但 Django 自带了一些其他的模板加载器，它们知道如何从其他来源加载模板。</p>\n<p>其他一些加载器默认是禁用的，但是你可以通过在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a> 配置中为你的 <code class=\"docutils literal notranslate\">DjangoTemplates</code> 后端添加一个 <code class=\"docutils literal notranslate\">'loaders'</code> 选项来激活它们，或者向 <a class=\"reference internal\" href=\"#django.template.Engine\" title=\"django.template.Engine\"><code class=\"xref py py-class docutils literal notranslate\">Engine</code></a> 传递一个 <code class=\"docutils literal notranslate\">loaders</code> 参数。<code class=\"docutils literal notranslate\">loaders</code> 应该是一个字符串或元组的列表，每个元组代表一个模板加载器类。下面是 Django 自带的模板加载器。</p>\n<p><code class=\"docutils literal notranslate\">django.template.loaders.filesystem.Loader</code></p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.filesystem.Loader\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-prename descclassname\">filesystem.</span><span class=\"sig-name descname\">Loader</span><a class=\"heading-anchor\" href=\"#django.template.loaders.filesystem.Loader\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>根据 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> 从文件系统加载模板。</p>\n<p>这个加载器默认是启用的。然而，它不会找到任何模板，直到你将 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES-DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">DIRS</code></a> 设置为非空列表：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;DIRS&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>BASE_DIR <span class=\"o\">/</span> <span class=\"s2\">&quot;templates&quot;</span><span class=\"p\">],</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>你也可以覆盖 <code class=\"docutils literal notranslate\">'DIRS'</code>，为特定的文件系统加载器指定特定的目录：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;OPTIONS&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;loaders&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n                <span class=\"p\">(</span>\n                    <span class=\"s2\">&quot;django.template.loaders.filesystem.Loader&quot;</span><span class=\"p\">,</span>\n                    <span class=\"p\">[</span>BASE_DIR <span class=\"o\">/</span> <span class=\"s2\">&quot;templates&quot;</span><span class=\"p\">],</span>\n                <span class=\"p\">),</span>\n            <span class=\"p\">],</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n</dd></dl>\n\n<p><code class=\"docutils literal notranslate\">django.template.loaders.app_directories.Loader</code></p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.app_directories.Loader\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-prename descclassname\">app_directories.</span><span class=\"sig-name descname\">Loader</span><a class=\"heading-anchor\" href=\"#django.template.loaders.app_directories.Loader\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>从文件系统中加载 Django 应用的模板。对于 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 中的每个应用，加载器会寻找一个 <code class=\"docutils literal notranslate\">templates</code> 子目录。如果该目录存在，Django 就会在其中寻找模板。</p>\n<p>这意味着你可以将模板与你的各个应用一起存储。这也有助于分发带有默认模板的 Django 应用。</p>\n<p>例如，对于这个配置：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>INSTALLED_APPS <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;myproject.polls&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;myproject.music&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>...然后 <code class=\"docutils literal notranslate\">get_template('foo.html')</code> 将在这些目录中按这个顺序查找 <code class=\"docutils literal notranslate\">foo.html</code>：</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">/path/to/myproject/polls/templates/</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">/path/to/myproject/music/templates/</code></p></li>\n</ul>\n<p>...会用它最先找到的那个：</p>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 的顺序很重要！例如，如果你想自定义 Django 管理，你可能会选择覆盖标准 <code class=\"docutils literal notranslate\">django.contrib.admin</code> 的 <code class=\"docutils literal notranslate\">admin/base_site.html</code> 模板，，用你自己 <code class=\"docutils literal notranslate\">myproject.polls</code> 中的 <code class=\"docutils literal notranslate\">admin/base_site.html</code>。然后你必须确保你的 <code class=\"docutils literal notranslate\">myproject.polls</code> 在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 中在 <code class=\"docutils literal notranslate\">django.contrib.admin</code> <em>之前</em>，否则 <code class=\"docutils literal notranslate\">django.contrib.admin</code> 的会先被加载，你的会被忽略。</p>\n<p>请注意，加载器在第一次运行时进行了优化：它缓存了一个列表，显示哪些 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 包有一个 <code class=\"docutils literal notranslate\">templates</code> 子目录。</p>\n<p>你可以通过设置 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES-APP_DIRS\"><code class=\"xref std std-setting docutils literal notranslate\">APP_DIRS</code></a> 为 <code class=\"docutils literal notranslate\">True</code> 来启用该加载器：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;APP_DIRS&quot;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n</dd></dl>\n\n<p><code class=\"docutils literal notranslate\">django.template.loaders.cached.Loader</code></p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.cached.Loader\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-prename descclassname\">cached.</span><span class=\"sig-name descname\">Loader</span><a class=\"heading-anchor\" href=\"#django.template.loaders.cached.Loader\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>虽然 Django 的模板系统非常快，但如果它每次渲染模板时都需要读取和编译模板，那么由此产生的开销可能会累积起来。</p>\n<p>你可以用其他加载器的列表来配置缓存的模板加载器，它应该对这些加载器进行封装。当第一次遇到未知模板时，封装的加载器被用来定位它们。然后，缓存加载器将编译后的 <code class=\"docutils literal notranslate\">Template</code> 存储在内存中。缓存的 <code class=\"docutils literal notranslate\">Template</code> 实例会被返回，供后续加载同一模板的请求使用。</p>\n<p>如果未指定 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-TEMPLATES-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS['loaders']</code></a>，则会自动启用此加载程序。</p>\n<p>您可以使用以下设置手动指定一些自定义模板加载程序的模板缓存方式：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;DIRS&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>BASE_DIR <span class=\"o\">/</span> <span class=\"s2\">&quot;templates&quot;</span><span class=\"p\">],</span>\n        <span class=\"s2\">&quot;OPTIONS&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;loaders&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n                <span class=\"p\">(</span>\n                    <span class=\"s2\">&quot;django.template.loaders.cached.Loader&quot;</span><span class=\"p\">,</span>\n                    <span class=\"p\">[</span>\n                        <span class=\"s2\">&quot;django.template.loaders.filesystem.Loader&quot;</span><span class=\"p\">,</span>\n                        <span class=\"s2\">&quot;django.template.loaders.app_directories.Loader&quot;</span><span class=\"p\">,</span>\n                        <span class=\"s2\">&quot;path.to.custom.Loader&quot;</span><span class=\"p\">,</span>\n                    <span class=\"p\">],</span>\n                <span class=\"p\">),</span>\n            <span class=\"p\">],</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>所有内置的 Django 模板标签都可以安全地使用缓存加载器，但如果你使用的是来自第三方包的自定义模板标签，或者你自己编写的模板标签，你应该确保每个标签的“节点”实现是线程安全的。更多信息，请参见 <a class=\"reference internal\" href=\"/zh-hans/6.1/howto/custom-template-tags/#template-tag-thread-safety\"><span class=\"std std-ref\">模板标签线程安全注意事项</span></a>。</p>\n</aside>\n</dd></dl>\n\n<p><code class=\"docutils literal notranslate\">django.template.loaders.locmem.Loader</code></p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.locmem.Loader\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-prename descclassname\">locmem.</span><span class=\"sig-name descname\">Loader</span><a class=\"heading-anchor\" href=\"#django.template.loaders.locmem.Loader\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>从 Python 字典中加载模板。这对测试很有用。</p>\n<p>该加载器将模板字典作为其第一个参数：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>TEMPLATES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;BACKEND&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.template.backends.django.DjangoTemplates&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;OPTIONS&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;loaders&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n                <span class=\"p\">(</span>\n                    <span class=\"s2\">&quot;django.template.loaders.locmem.Loader&quot;</span><span class=\"p\">,</span>\n                    <span class=\"p\">{</span>\n                        <span class=\"s2\">&quot;index.html&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;content here&quot;</span><span class=\"p\">,</span>\n                    <span class=\"p\">},</span>\n                <span class=\"p\">),</span>\n            <span class=\"p\">],</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>该加载器默认为禁用。</p>\n</dd></dl>\n\n<p>Django 根据 <code class=\"docutils literal notranslate\">'loaders'</code> 选项的顺序使用模板加载器。它使用每个加载器，直到一个加载器找到匹配的模板。</p>\n</section>\n</section>\n<section id=\"custom-loaders\">\n<span id=\"custom-template-loaders\"></span><h2>自定义加载器<a class=\"heading-anchor\" href=\"#custom-loaders\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>可以使用自定义模板加载器从其他来源加载模板。自定义 <code class=\"docutils literal notranslate\">Loader</code> 类应该继承 <code class=\"docutils literal notranslate\">django.template.loaders.base.Loader</code> 并定义 <code class=\"docutils literal notranslate\">get_contents()</code> 和 <code class=\"docutils literal notranslate\">get_template_sources()</code> 方法。</p>\n<section id=\"loader-methods\">\n<h3>加载器方法<a class=\"heading-anchor\" href=\"#loader-methods\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.base.Loader\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Loader</span><a class=\"heading-anchor\" href=\"#django.template.loaders.base.Loader\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>从给定的源，如文件系统或数据库中加载模板。</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.base.Loader.get_template_sources\">\n<span class=\"sig-name descname\">get_template_sources</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">template_name</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.loaders.base.Loader.get_template_sources\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>一个接受 <code class=\"docutils literal notranslate\">template_name</code> 的方法，并为每个可能的来源产生 <a class=\"reference internal\" href=\"#django.template.base.Origin\" title=\"django.template.base.Origin\"><code class=\"xref py py-class docutils literal notranslate\">Origin</code></a> 实例。</p>\n<p>For example, the filesystem loader may receive <code class=\"docutils literal notranslate\">'index.html'</code> as a\n<code class=\"docutils literal notranslate\">template_name</code> argument. This method would yield origins for the\nfull path of <code class=\"docutils literal notranslate\">index.html</code> as it appears in each template directory\nthe loader looks at.</p>\n<p>该方法不需要验证模板是否存在于给定的路径中，但它应该确保路径是有效的。例如，文件系统加载器会确保路径位于一个有效的模板目录下。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.base.Loader.get_contents\">\n<span class=\"sig-name descname\">get_contents</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">origin</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.loaders.base.Loader.get_contents\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>返回给定 <a class=\"reference internal\" href=\"#django.template.base.Origin\" title=\"django.template.base.Origin\"><code class=\"xref py py-class docutils literal notranslate\">Origin</code></a> 实例的模板的内容。</p>\n<p>这是一个文件系统加载器从文件系统读取内容的地方，或者一个数据库加载器从数据库读取内容的地方。如果一个匹配的模板不存在，这应该会引发一个 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.TemplateDoesNotExist\" title=\"django.template.TemplateDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\">TemplateDoesNotExist</code></a> 错误。</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.loaders.base.Loader.get_template\">\n<span class=\"sig-name descname\">get_template</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">template_name</em>, <em class=\"sig-param\">skip<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.loaders.base.Loader.get_template\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>通过循环浏览 <a class=\"reference internal\" href=\"#django.template.loaders.base.Loader.get_template_sources\" title=\"django.template.loaders.base.Loader.get_template_sources\"><code class=\"xref py py-meth docutils literal notranslate\">get_template_sources()</code></a> 和调用 <a class=\"reference internal\" href=\"#django.template.loaders.base.Loader.get_contents\" title=\"django.template.loaders.base.Loader.get_contents\"><code class=\"xref py py-meth docutils literal notranslate\">get_contents()</code></a> 的结果，为给定的 <code class=\"docutils literal notranslate\">template_name</code> 返回一个 <code class=\"docutils literal notranslate\">Template</code> 对象。这将返回第一个匹配的模板。如果没有找到模板，则会引发 <a class=\"reference internal\" href=\"/zh-hans/6.1/topics/templates/#django.template.TemplateDoesNotExist\" title=\"django.template.TemplateDoesNotExist\"><code class=\"xref py py-exc docutils literal notranslate\">TemplateDoesNotExist</code></a>。</p>\n<p>可选的 <code class=\"docutils literal notranslate\">skip</code> 参数是扩展模板时要忽略的起源列表。这允许模板扩展同名的其他模板。它也用于避免递归错误。</p>\n<p>一般来说，定义 <a class=\"reference internal\" href=\"#django.template.loaders.base.Loader.get_template_sources\" title=\"django.template.loaders.base.Loader.get_template_sources\"><code class=\"xref py py-meth docutils literal notranslate\">get_template_sources()</code></a> 和 <a class=\"reference internal\" href=\"#django.template.loaders.base.Loader.get_contents\" title=\"django.template.loaders.base.Loader.get_contents\"><code class=\"xref py py-meth docutils literal notranslate\">get_contents()</code></a> 为自定义模板加载器就可以了。<code class=\"docutils literal notranslate\">get_template()</code> 通常不需要重写。</p>\n</dd></dl>\n\n</dd></dl>\n\n<aside class=\"admonition-building-your-own admonition\" role=\"note\">\n<p class=\"admonition-title\">构建你自己的</p>\n<p>例如，请阅读 <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/6.1.x/django/template/loaders\">Django 内置加载器的源代码</a>。</p>\n</aside>\n</section>\n</section>\n<section id=\"template-origin\">\n<h2>模板起源<a class=\"heading-anchor\" href=\"#template-origin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>模板有一个 <code class=\"docutils literal notranslate\">origin</code>，包含的属性取决于它们的来源。</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.template.base.Origin\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Origin</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">name</em>, <em class=\"sig-param\">template_name<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">loader<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.base.Origin\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.template.base.Origin.name\">\n<span class=\"sig-name descname\">name</span><a class=\"heading-anchor\" href=\"#django.template.base.Origin.name\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>模板加载器返回的模板路径。对于从文件系统读取的加载器，这是模板的完整路径。</p>\n<p>如果模板是直接实例化的，而不是通过模板加载器，这是一个字符串值 <code class=\"docutils literal notranslate\">&lt;unknown_source&gt;</code>。</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.template.base.Origin.template_name\">\n<span class=\"sig-name descname\">template_name</span><a class=\"heading-anchor\" href=\"#django.template.base.Origin.template_name\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>传入模板加载器的模板的相对路径。</p>\n<p>如果模板是直接实例化的，而不是通过模板加载器，这就是 <code class=\"docutils literal notranslate\">None</code>。</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.template.base.Origin.loader\">\n<span class=\"sig-name descname\">loader</span><a class=\"heading-anchor\" href=\"#django.template.base.Origin.loader\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>构建这个 <code class=\"docutils literal notranslate\">Origin</code> 的模板加载器实例。</p>\n<p>如果模板是直接实例化的，而不是通过模板加载器，这就是 <code class=\"docutils literal notranslate\">None</code>。</p>\n<p><a class=\"reference internal\" href=\"#django.template.loaders.cached.Loader\" title=\"django.template.loaders.cached.Loader\"><code class=\"xref py py-class docutils literal notranslate\">django.template.loaders.cached.Loader</code></a> 要求所有封装的加载器都要设置这个属性，通常是通过实例化 <code class=\"docutils literal notranslate\">loader=self</code> 的 <code class=\"docutils literal notranslate\">Origin</code>。</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>","rootId":"the-django-template-language-for-python-programmers","toc":[{"title":"概况","anchor":"overview","children":[]},{"title":"设置引擎","anchor":"configuring-an-engine","children":[]},{"title":"加载模板","anchor":"loading-a-template","children":[]},{"title":"渲染上下文","anchor":"rendering-a-context","children":[{"title":"变量和查找","anchor":"variables-and-lookups","children":[]},{"title":"如何处理无效变量","anchor":"how-invalid-variables-are-handled","children":[]},{"title":"内置变量","anchor":"built-in-variables","children":[]},{"title":"字符串的限制","anchor":"limitations-with-string-literals","children":[]}]},{"title":"使用 Context 对象","anchor":"playing-with-context-objects","children":[{"title":"使用 RequestContext","anchor":"using-requestcontext","children":[]},{"title":"内置模板上下文处理器","anchor":"built-in-template-context-processors","children":[{"title":"django.contrib.auth.context_processors.auth","anchor":"django-contrib-auth-context-processors-auth","children":[]},{"title":"django.template.context_processors.debug","anchor":"django-template-context-processors-debug","children":[]},{"title":"django.template.context_processors.i18n","anchor":"django-template-context-processors-i18n","children":[]},{"title":"django.template.context_processors.media","anchor":"django-template-context-processors-media","children":[]},{"title":"django.template.context_processors.static","anchor":"django-template-context-processors-static","children":[]},{"title":"django.template.context_processors.csrf","anchor":"django-template-context-processors-csrf","children":[]},{"title":"django.template.context_processors.csp","anchor":"django-template-context-processors-csp","children":[]},{"title":"django.template.context_processors.request","anchor":"django-template-context-processors-request","children":[]},{"title":"django.template.context_processors.tz","anchor":"django-template-context-processors-tz","children":[]},{"title":"django.contrib.messages.context_processors.messages","anchor":"django-contrib-messages-context-processors-messages","children":[]}]},{"title":"编写你自己的上下文处理器","anchor":"writing-your-own-context-processors","children":[]}]},{"title":"加载模板","anchor":"loading-templates","children":[{"title":"DIRS 选项","anchor":"the-dirs-option","children":[]},{"title":"加载器类型","anchor":"loader-types","children":[]}]},{"title":"自定义加载器","anchor":"custom-loaders","children":[{"title":"加载器方法","anchor":"loader-methods","children":[]}]},{"title":"模板起源","anchor":"template-origin","children":[]}],"breadcrumbs":[{"docname":"ref/index","title":"API 参考","url":"/zh-hans/6.1/ref/"},{"docname":"ref/templates/index","title":"模板","url":"/zh-hans/6.1/ref/templates/"}],"prev":{"docname":"ref/templates/builtins","title":"内置模板标签和过滤器","url":"/zh-hans/6.1/ref/templates/builtins/"},"next":{"docname":"ref/template-response","title":"TemplateResponse 和 SimpleTemplateResponse","url":"/zh-hans/6.1/ref/template-response/"},"formats":{"html":"/zh-hans/6.1/ref/templates/api/","markdown":"/zh-hans/6.1/ref/templates/api.md","json":"/zh-hans/6.1/ref/templates/api.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/ref/templates/api.txt","official":"https://docs.djangoproject.com/zh-hans/6.1/ref/templates/api/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}