
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_Hans">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Django 模板语言：对于 Python 开发者 &#8212; Django 3.2.11.dev 文档</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/language_data.js"></script>
    <link rel="index" title="索引" href="../../genindex.html" />
    <link rel="search" title="搜索" href="../../search.html" />
    <link rel="next" title="TemplateResponse 和 SimpleTemplateResponse" href="../template-response.html" />
    <link rel="prev" title="内置模板标签和过滤器" href="builtins.html" />



 
<script src="../../templatebuiltins.js"></script>
<script>
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django 3.2.11.dev 文档</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="builtins.html" title="内置模板标签和过滤器">previous</a>
     |
    <a href="../index.html" title="API 参考" accesskey="U">up</a>
   |
    <a href="../template-response.html" title="&lt;code class=&#34;docutils literal notranslate&#34;&gt;&lt;span class=&#34;pre&#34;&gt;TemplateResponse&lt;/span&gt;&lt;/code&gt; 和 &lt;code class=&#34;docutils literal notranslate&#34;&gt;&lt;span class=&#34;pre&#34;&gt;SimpleTemplateResponse&lt;/span&gt;&lt;/code&gt;">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="ref-templates-api">
            
  <div class="section" id="s-the-django-template-language-for-python-programmers">
<span id="the-django-template-language-for-python-programmers"></span><h1>Django 模板语言：对于 Python 开发者<a class="headerlink" href="#the-django-template-language-for-python-programmers" title="永久链接至标题">¶</a></h1>
<p>这篇文档从技术角度解释了 Django 模板系统——它是如何工作的以及如何扩展它。如果你想找语言语法的参考，请看 <a class="reference internal" href="language.html"><span class="doc">Django 模板语言</span></a>。</p>
<p>它的前提是对模板、上下文、变量、标签和渲染的理解。如果你不熟悉这些概念，可以从 <a class="reference internal" href="../../topics/templates.html#template-language-intro"><span class="std std-ref">Django 模板语言介绍</span></a> 开始。</p>
<div class="section" id="s-overview">
<span id="overview"></span><h2>概况<a class="headerlink" href="#overview" title="永久链接至标题">¶</a></h2>
<p>在 Python 中使用模板系统是一个三步走的过程：</p>
<ol class="arabic simple">
<li>你设置了一个 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a>。</li>
<li>你把模板代码编译成一个 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>。</li>
<li>你用一个 <a class="reference internal" href="#django.template.Context" title="django.template.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> 来渲染模板。</li>
</ol>
<p>Django 项目一般依靠 <a class="reference internal" href="../../topics/templates.html#template-engines"><span class="std std-ref">高级、后端不可知的 API</span></a> 来完成每一个步骤，而不是模板系统的低级 API。</p>
<ol class="arabic simple">
<li>对于 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">TEMPLATES</span></code></a> 设置中的每一个 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 后端，Django 都会实例化一个 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a>。 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 封装 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a> 并将其适配到通用的模板后端 API 中。</li>
<li><a class="reference internal" href="../../topics/templates.html#module-django.template.loader" title="django.template.loader"><code class="xref py py-mod docutils literal notranslate"><span class="pre">django.template.loader</span></code></a> 模块提供了 <a class="reference internal" href="../../topics/templates.html#django.template.loader.get_template" title="django.template.loader.get_template"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_template()</span></code></a> 等函数来加载模板。它们返回一个 <code class="docutils literal notranslate"><span class="pre">django.template.backends.django.Template</span></code>，它封装了实际的 <a class="reference internal" href="../../topics/templates.html#module-django.template" title="django.template: Django's template system"><code class="xref py py-class docutils literal notranslate"><span class="pre">django.template</span></code></a>。</li>
<li>上一步得到的 <code class="docutils literal notranslate"><span class="pre">Template</span></code> 有一个 <a class="reference internal" href="../../topics/templates.html#django.template.backends.base.Template.render" title="django.template.backends.base.Template.render"><code class="xref py py-meth docutils literal notranslate"><span class="pre">render()</span></code></a> 方法，它将一个上下文和可能的请求汇集到一个 <a class="reference internal" href="#django.template.Context" title="django.template.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> 中，并委托底层的 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> 进行渲染。</li>
</ol>
</div>
<div class="section" id="s-configuring-an-engine">
<span id="configuring-an-engine"></span><h2>设置引擎<a class="headerlink" href="#configuring-an-engine" title="永久链接至标题">¶</a></h2>
<p>如果你使用的是 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 后端，这可能不是你要找的文档。下面描述的 <code class="docutils literal notranslate"><span class="pre">Engine</span></code> 类的实例可以通过该后端的 <code class="docutils literal notranslate"><span class="pre">engine</span></code> 属性来访问，下面提到的任何属性默认值都会被 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 传递的内容所覆盖。</p>
<dl class="class">
<dt id="django.template.Engine">
<em class="property">class </em><code class="descname">Engine</code>(<em>dirs=None</em>, <em>app_dirs=False</em>, <em>context_processors=None</em>, <em>debug=False</em>, <em>loaders=None</em>, <em>string_if_invalid=''</em>, <em>file_charset='utf-8'</em>, <em>libraries=None</em>, <em>builtins=None</em>, <em>autoescape=True</em>)<a class="headerlink" href="#django.template.Engine" title="永久链接至目标">¶</a></dt>
<dd><p>当实例化一个 <code class="docutils literal notranslate"><span class="pre">Engine</span></code> 时，所有的参数都必须作为关键字参数传递。</p>
<ul>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">dirs</span></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"><span class="pre">filesystem.Loader</span></code></a>。</p>
<p>默认为空列表。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">app_dirs</span></code> 只影响 <code class="docutils literal notranslate"><span class="pre">loaders</span></code> 的默认值。见下文。</p>
<p>默认为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">autoescape</span></code> 控制是否启用 HTML 自动转码。</p>
<p>默认为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">只有当你渲染非 HTML 模板时，才将其设置为 <code class="docutils literal notranslate"><span class="pre">False</span></code>！</p>
</div>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">context_processors</span></code> 是一个点分隔 Python 路径的列表，当一个模板被请求渲染时，这些可调用对象被用来填充上下文。这些可调用对象以一个请求对象作为参数，并返回一个 <a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#dict" title="(在 Python v3.10)"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> 的项目，这些项目将被合并到上下文中。</p>
<p>默认为空列表。</p>
<p>查看 <a class="reference internal" href="#django.template.RequestContext" title="django.template.RequestContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">RequestContext</span></code></a> 获取更多信息。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">debug</span></code> 是一个开启／关闭模板调试模式的布尔值。如果它为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，模板引擎将存储额外的调试信息，这些信息可用于显示模板渲染过程中出现的任何异常的详细报告。</p>
<p>默认为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">loaders</span></code> 是一个模板加载器类的列表，以字符串形式指定。每个 <code class="docutils literal notranslate"><span class="pre">Loader</span></code> 类都知道如何从特定来源导入模板。可以选择使用元组来代替字符串。元组中的第一项应该是 <code class="docutils literal notranslate"><span class="pre">Loader</span></code> 类名，随后的项目在初始化时传递给 <code class="docutils literal notranslate"><span class="pre">Loader</span></code>。</p>
<p>它默认为包含以下内容的列表：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">'django.template.loaders.filesystem.Loader'</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">'django.template.loaders.app_directories.Loader'</span></code> 如果且仅当 <code class="docutils literal notranslate"><span class="pre">app_dirs</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时。</li>
</ul>
<p>如果 <code class="docutils literal notranslate"><span class="pre">debug</span></code> 是 <code class="docutils literal notranslate"><span class="pre">False</span></code>，这些加载器被封装在 <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"><span class="pre">django.template.loaders.cached.Loader</span></code></a> 中。</p>
<p>查看 <a class="reference internal" href="#template-loaders"><span class="std std-ref">加载器类型</span></a> 获取详细信息。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 是模板系统对无效变量（如拼写错误）应使用的字符串输出。</p>
<p>默认为空字符串。</p>
<p>查看 <a class="reference internal" href="#invalid-template-variables"><span class="std std-ref">如何处理无效变量</span></a> 获取更多信息。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">file_charset</span></code> 是用来读取磁盘上模板文件的字符集。</p>
<p>默认为 <code class="docutils literal notranslate"><span class="pre">'utf-8'</span></code>。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">'libraries'</span></code>：模板标签模块的标签和点分隔 Python 路径字典，用于向模板引擎注册。它用于添加新库或为现有库提供替代标签。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Engine</span><span class="p">(</span>
    <span class="n">libraries</span><span class="o">=</span><span class="p">{</span>
        <span class="s1">&#39;myapp_tags&#39;</span><span class="p">:</span> <span class="s1">&#39;path.to.myapp.tags&#39;</span><span class="p">,</span>
        <span class="s1">&#39;admin.urls&#39;</span><span class="p">:</span> <span class="s1">&#39;django.contrib.admin.templatetags.admin_urls&#39;</span><span class="p">,</span>
    <span class="p">},</span>
<span class="p">)</span>
</pre></div>
</div>
<p>可以通过将相应的字典键传递到 <a class="reference internal" href="builtins.html#std:templatetag-load"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">%}</span></code></a> 标签来加载库。</p>
</li>
<li><p class="first"><code class="docutils literal notranslate"><span class="pre">'builtins'</span></code>：要添加的 <a class="reference internal" href="builtins.html"><span class="doc">内置模板标签和过滤器</span></a> 的点分隔 Python 路径列表。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Engine</span><span class="p">(</span>
    <span class="n">builtins</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;myapp.builtins&#39;</span><span class="p">],</span>
<span class="p">)</span>
</pre></div>
</div>
<p>可以使用内置库中的标签和过滤器，而不需要先调用 <a class="reference internal" href="builtins.html#std:templatetag-load"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">%}</span></code></a> 标签。</p>
</li>
</ul>
</dd></dl>

<dl class="staticmethod">
<dt id="django.template.Engine.get_default">
<em class="property">static </em><code class="descclassname">Engine.</code><code class="descname">get_default</code>()<a class="headerlink" href="#django.template.Engine.get_default" title="永久链接至目标">¶</a></dt>
<dd><p>从第一个配置的 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 引擎中返回底层 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a>。如果没有配置引擎，则引发 <a class="reference internal" href="../exceptions.html#django.core.exceptions.ImproperlyConfigured" title="django.core.exceptions.ImproperlyConfigured"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImproperlyConfigured</span></code></a>。</p>
<p>这是为保存依赖于全局可用、隐式配置引擎的 API 所必需的。任何其他用途都是不鼓励的。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.Engine.from_string">
<code class="descclassname">Engine.</code><code class="descname">from_string</code>(<em>template_code</em>)<a class="headerlink" href="#django.template.Engine.from_string" title="永久链接至目标">¶</a></dt>
<dd><p>编译给定的模板代码并返回一个 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> 对象。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.Engine.get_template">
<code class="descclassname">Engine.</code><code class="descname">get_template</code>(<em>template_name</em>)<a class="headerlink" href="#django.template.Engine.get_template" title="永久链接至目标">¶</a></dt>
<dd><p>加载给定名称的模板，编译后返回一个 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> 对象。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.Engine.select_template">
<code class="descclassname">Engine.</code><code class="descname">select_template</code>(<em>template_name_list</em>)<a class="headerlink" href="#django.template.Engine.select_template" title="永久链接至目标">¶</a></dt>
<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"><span class="pre">get_template()</span></code></a> 一样，只不过它接收一个名称列表，并返回找到的第一个模板。</p>
</dd></dl>

</div>
<div class="section" id="s-loading-a-template">
<span id="loading-a-template"></span><h2>加载模板<a class="headerlink" href="#loading-a-template" title="永久链接至标题">¶</a></h2>
<p>推荐的创建 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> 的方法是调用 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></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"><span class="pre">get_template()</span></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"><span class="pre">select_template()</span></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"><span class="pre">from_string()</span></code></a>。</p>
<p>在 Django 项目中，如果 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">TEMPLATES</span></code></a> 设置定义了一个 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 引擎，那么可以直接实例化一个 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a>。如果定义了多个 <a class="reference internal" href="../../topics/templates.html#django.template.backends.django.DjangoTemplates" title="django.template.backends.django.DjangoTemplates"><code class="xref py py-class docutils literal notranslate"><span class="pre">DjangoTemplates</span></code></a> 引擎，则使用第一个引擎。</p>
<dl class="class">
<dt id="django.template.Template">
<em class="property">class </em><code class="descname">Template</code><a class="headerlink" href="#django.template.Template" title="永久链接至目标">¶</a></dt>
<dd><p>这个类位于 <code class="docutils literal notranslate"><span class="pre">django.template.Template</span></code>。构造函数需要一个参数——原始模板代码：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">Template</span>

<span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">&quot;My name is {{ my_name }}.&quot;</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>

<div class="admonition-behind-the-scenes admonition">
<p class="first admonition-title">幕后</p>
<p>系统只在创建 <code class="docutils literal notranslate"><span class="pre">Template</span></code> 对象时解析一次原始模板代码。从那时起，为了提高性能，它将以树结构的形式存储在内部。</p>
<p class="last">即使是解析本身也是相当快的。大部分的解析工作都是通过调用一个简短的正则表达式来完成的。</p>
</div>
</div>
<div class="section" id="s-rendering-a-context">
<span id="rendering-a-context"></span><h2>渲染上下文<a class="headerlink" href="#rendering-a-context" title="永久链接至标题">¶</a></h2>
<p>一旦你有一个编译过的 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> 对象，你就可以用它来渲染一个上下文。你可以重复使用同一个模板，在不同的上下文中多次渲染它。</p>
<dl class="class">
<dt id="django.template.Context">
<em class="property">class </em><code class="descname">Context</code>(<em>dict_=None</em>)<a class="headerlink" href="#django.template.Context" title="永久链接至目标">¶</a></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">django.template.Context</span></code> 的构造函数需要一个可选的参数——一个将变量名映射到变量值的字典。</p>
<p>详情请看下面的 <a class="reference internal" href="#playing-with-context"><span class="std std-ref">使用 Context 对象</span></a>。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.Template.render">
<code class="descclassname">Template.</code><code class="descname">render</code>(<em>context</em>)<a class="headerlink" href="#django.template.Template.render" title="永久链接至目标">¶</a></dt>
<dd><p>用一个 <a class="reference internal" href="#django.template.Context" title="django.template.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> 调用 <a class="reference internal" href="#django.template.Template" title="django.template.Template"><code class="xref py py-class docutils literal notranslate"><span class="pre">Template</span></code></a> 对象的 <code class="docutils literal notranslate"><span class="pre">render()</span></code> 方法来“填充”模板：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">Context</span><span class="p">,</span> <span class="n">Template</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">&quot;My name is {{ my_name }}.&quot;</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">context</span> <span class="o">=</span> <span class="n">Context</span><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>
<span class="gp">&gt;&gt;&gt; </span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="go">&quot;My name is Adrian.&quot;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">context</span> <span class="o">=</span> <span class="n">Context</span><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>
<span class="gp">&gt;&gt;&gt; </span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="go">&quot;My name is Dolores.&quot;</span>
</pre></div>
</div>
</dd></dl>

<div class="section" id="s-variables-and-lookups">
<span id="variables-and-lookups"></span><h3>变量和查找<a class="headerlink" href="#variables-and-lookups" title="永久链接至标题">¶</a></h3>
<p>变量名称必须由任何字母（A-Z）、任何数字（0-9）、下划线（但不得以下划线开头）或点组成。</p>
<p>点在模板渲染中具有特殊的意义。变量名中的点表示 <strong>查找</strong>。具体来说，当模板系统遇到变量名中的点时，它将按照以下顺序尝试进行查找：</p>
<ul class="simple">
<li>词典查找。例如：<code class="docutils literal notranslate"><span class="pre">foo[&quot;bar&quot;]</span></code></li>
<li>属性查找。例如：<code class="docutils literal notranslate"><span class="pre">foo.bar</span></code></li>
<li>列表索引查找。例如：<code class="docutils literal notranslate"><span class="pre">foo[bar]</span></code></li>
</ul>
<p>请注意，像 <code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">foo.bar</span> <span class="pre">}}</span></code> 这样的模板表达式中的“bar”将被解释为一个字面字符串，而不是使用变量“bar”的值，如果模板上下文中存在的话。</p>
<p>模板系统使用的是第一种有效的查找类型。这是短路逻辑。下面是几个例子：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">Context</span><span class="p">,</span> <span class="n">Template</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">&quot;My name is {{ person.first_name }}.&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">d</span> <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>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">Context</span><span class="p">(</span><span class="n">d</span><span class="p">))</span>
<span class="go">&quot;My name is Joe.&quot;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">PersonClass</span><span class="p">:</span> <span class="k">pass</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span> <span class="o">=</span> <span class="n">PersonClass</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span><span class="o">.</span><span class="n">first_name</span> <span class="o">=</span> <span class="s2">&quot;Ron&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span><span class="o">.</span><span class="n">last_name</span> <span class="o">=</span> <span class="s2">&quot;Nasty&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">Context</span><span class="p">({</span><span class="s2">&quot;person&quot;</span><span class="p">:</span> <span class="n">p</span><span class="p">}))</span>
<span class="go">&quot;My name is Ron.&quot;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">&quot;The first stooge in the list is {{ stooges.0 }}.&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><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>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="go">&quot;The first stooge in the list is Larry.&quot;</span>
</pre></div>
</div>
<p>如果变量的任何部分是可调用对象，模板系统将尝试调用它。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">PersonClass2</span><span class="p">:</span>
<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>
<span class="gp">... </span>        <span class="k">return</span> <span class="s2">&quot;Samantha&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">&quot;My name is {{ person.name }}.&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">Context</span><span class="p">({</span><span class="s2">&quot;person&quot;</span><span class="p">:</span> <span class="n">PersonClass2</span><span class="p">}))</span>
<span class="go">&quot;My name is Samantha.&quot;</span>
</pre></div>
</div>
<p>可调用对象的变量比只需要直接查找的变量要复杂一些。下面是一些需要注意的事项：</p>
<ul>
<li><p class="first">如果变量在调用时引发异常，那么异常将被传播，除非异常有一个属性 <code class="docutils literal notranslate"><span class="pre">silent_variable_failure</span></code>，其值为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。如果异常 <em>有</em> 一个 <cite>silent_variable_failure`</cite> 属性，其值为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，则该变量将作为引擎的 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 配置选项的值（默认为空字符串）。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s2">&quot;My name is {{ person.first_name }}.&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">PersonClass3</span><span class="p">:</span>
<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>
<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>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span> <span class="o">=</span> <span class="n">PersonClass3</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">Context</span><span class="p">({</span><span class="s2">&quot;person&quot;</span><span class="p">:</span> <span class="n">p</span><span class="p">}))</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">AssertionError</span>: <span class="n">foo</span>

<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>
<span class="gp">... </span>    <span class="n">silent_variable_failure</span> <span class="o">=</span> <span class="kc">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">PersonClass4</span><span class="p">:</span>
<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>
<span class="gp">... </span>        <span class="k">raise</span> <span class="n">SilentAssertionError</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span> <span class="o">=</span> <span class="n">PersonClass4</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">Context</span><span class="p">({</span><span class="s2">&quot;person&quot;</span><span class="p">:</span> <span class="n">p</span><span class="p">}))</span>
<span class="go">&quot;My name is .&quot;</span>
</pre></div>
</div>
<p>请注意 <a class="reference internal" href="../exceptions.html#django.core.exceptions.ObjectDoesNotExist" title="django.core.exceptions.ObjectDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">django.core.exceptions.ObjectDoesNotExist</span></code></a> 是所有 Django 数据库 API <code class="docutils literal notranslate"><span class="pre">DoesNotExist</span></code> 异常的基类，有 <code class="docutils literal notranslate"><span class="pre">silent_variable_failure</span> <span class="pre">=</span> <span class="pre">True</span></code>。所以如果你使用 Django 模板与 Django 模型对象，任何 <code class="docutils literal notranslate"><span class="pre">DoesNotExist</span></code> 异常都会静默失败。</p>
</li>
<li><p class="first">一个变量只有在没有所需参数的情况下才可以被调用，否则，系统将返回引擎的 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 选项的值。否则，系统将返回引擎的 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 选项的值。</p>
</li>
</ul>
<ul id="alters-data-description">
<li><p class="first">在调用一些变量的时候可能会有副作用，如果让模板系统访问这些变量，要么是傻瓜，要么是安全漏洞。</p>
<p>一个很好的例子是在每个 Django 模型对象上的 <a class="reference internal" href="../models/instances.html#django.db.models.Model.delete" title="django.db.models.Model.delete"><code class="xref py py-meth docutils literal notranslate"><span class="pre">delete()</span></code></a> 方法。模板系统不应该允许做这样的事情：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="n">will</span> <span class="n">now</span> <span class="n">delete</span> <span class="n">this</span> <span class="n">valuable</span> <span class="n">data</span><span class="o">.</span> <span class="p">{{</span> <span class="n">data</span><span class="o">.</span><span class="n">delete</span> <span class="p">}}</span>
</pre></div>
</div>
<p>为了防止这种情况发生，在可调用的变量上设置一个 <code class="docutils literal notranslate"><span class="pre">alters_data</span></code> 属性。如果设置了 <code class="docutils literal notranslate"><span class="pre">alters_data=True</span></code>，模板系统将不会调用变量，而是无条件地用 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 替换变量。 动态生成的 <a class="reference internal" href="../models/instances.html#django.db.models.Model.delete" title="django.db.models.Model.delete"><code class="xref py py-meth docutils literal notranslate"><span class="pre">delete()</span></code></a> 和 <code class="xref py py-meth docutils literal notranslate"><span class="pre">save()</span></code> 方法会自动获取 <code class="docutils literal notranslate"><span class="pre">alters_data=True</span></code>。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sensitive_function</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">database_record</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="n">sensitive_function</span><span class="o">.</span><span class="n">alters_data</span> <span class="o">=</span> <span class="kc">True</span>
</pre></div>
</div>
</li>
<li><p class="first">偶尔你可能会因为其他原因想关闭这个功能，并告诉模板系统无论如何都不调用一个变量。 要做到这一点，请在可调用变量上设置一个 <code class="docutils literal notranslate"><span class="pre">do_not_call_in_templates</span></code> 属性，其值为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。 这样，模板系统就会把你的变量当作不可调用的变量（例如，允许你访问可调用变量的属性）。</p>
</li>
</ul>
</div>
<div class="section" id="s-how-invalid-variables-are-handled">
<span id="s-invalid-template-variables"></span><span id="how-invalid-variables-are-handled"></span><span id="invalid-template-variables"></span><h3>如何处理无效变量<a class="headerlink" href="#how-invalid-variables-are-handled" title="永久链接至标题">¶</a></h3>
<p>一般来说，如果一个变量不存在，模板系统会插入引擎的 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 配置选项的值，默认设置为 <code class="docutils literal notranslate"><span class="pre">''</span></code> （空字符串）。</p>
<p>只有当 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 被设置为 <code class="docutils literal notranslate"><span class="pre">''</span></code> （空字符串）时，才会对无效变量应用过滤器。如果 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 被设置为任何其他值，变量过滤器将被忽略。</p>
<p>对于 <code class="docutils literal notranslate"><span class="pre">if</span></code>、<code class="docutils literal notranslate"><span class="pre">for</span></code> 和 <code class="docutils literal notranslate"><span class="pre">regroup</span></code> 模板标签，这种行为略有不同。如果向这些模板标签之一提供了一个无效的变量，该变量将被解释为 <code class="docutils literal notranslate"><span class="pre">None</span></code>。过滤器总是应用于这些模板标签中的无效变量。</p>
<p>如果 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 包含 <code class="docutils literal notranslate"><span class="pre">'%s'</span></code>，格式标记将被替换为无效变量的名称。</p>
<div class="admonition-for-debug-purposes-only admonition">
<p class="first admonition-title">仅供调试使用！</p>
<p>虽然 <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 是一个有用的调试工具，但把它作为“开发默认值”是一个坏主意。</p>
<p>很多模板，包括一些 Django 的模板，在遇到不存在的变量时，都会依靠模板系统的静默。如果你给 <code class="docutils literal notranslate"><span class="pre">''</span></code>  <code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 以外的值，你会在这些模板和网站上遇到渲染问题。</p>
<p class="last">一般来说，<code class="docutils literal notranslate"><span class="pre">string_if_invalid</span></code> 只有在调试某个特定的模板问题时才应该启用，调试完成后再清除。</p>
</div>
</div>
<div class="section" id="s-built-in-variables">
<span id="built-in-variables"></span><h3>内置变量<a class="headerlink" href="#built-in-variables" title="永久链接至标题">¶</a></h3>
<p>每个上下文都包含 <code class="docutils literal notranslate"><span class="pre">True</span></code>、<code class="docutils literal notranslate"><span class="pre">False</span></code> 和 <code class="docutils literal notranslate"><span class="pre">None</span></code>。正如你所期望的那样，这些变量解析为相应的 Python 对象。</p>
</div>
<div class="section" id="s-limitations-with-string-literals">
<span id="limitations-with-string-literals"></span><h3>字符串的限制<a class="headerlink" href="#limitations-with-string-literals" title="永久链接至标题">¶</a></h3>
<p>Django 的模板语言没有办法转义用于自己语法的字符。例如，如果你需要输出像 <code class="docutils literal notranslate"><span class="pre">{%</span></code> 和 <code class="docutils literal notranslate"><span class="pre">%}</span></code> 这样的字符序列，就需要使用 <a class="reference internal" href="builtins.html#std:templatetag-templatetag"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">templatetag</span></code></a> 标签。</p>
<p>如果你想把这些序列包含在模板过滤器或标签参数中，也存在类似的问题。例如，当解析一个区块标签时，Django 的模板解析器会在 <code class="docutils literal notranslate"><span class="pre">{%</span></code> 之后寻找第一次出现的 <code class="docutils literal notranslate"><span class="pre">%}</span></code>。这就避免了使用 <code class="docutils literal notranslate"><span class="pre">&quot;%}&quot;</span></code> 作为字符串文字。例如，以下表达式将引发 <code class="docutils literal notranslate"><span class="pre">TemplateSyntaxError</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="o">%</span> <span class="n">include</span> <span class="s2">&quot;template.html&quot;</span> <span class="n">tvar</span><span class="o">=</span><span class="s2">&quot;Some string literal with %} in it.&quot;</span> <span class="o">%</span><span class="p">}</span>

<span class="p">{</span><span class="o">%</span> <span class="k">with</span> <span class="n">tvar</span><span class="o">=</span><span class="s2">&quot;Some string literal with %} in it.&quot;</span> <span class="o">%</span><span class="p">}{</span><span class="o">%</span> <span class="n">endwith</span> <span class="o">%</span><span class="p">}</span>
</pre></div>
</div>
<p>同样的问题可以通过在过滤器参数中使用保留序列来触发：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{{</span> <span class="n">some</span><span class="o">.</span><span class="n">variable</span><span class="o">|</span><span class="n">default</span><span class="p">:</span><span class="s2">&quot;}}&quot;</span> <span class="p">}}</span>
</pre></div>
</div>
<p>如果你需要使用这些序列的字符串，请将它们存储在模板变量中，或者使用自定义模板标签或过滤器来解决这个限制。</p>
</div>
</div>
<div class="section" id="s-playing-with-context-objects">
<span id="s-playing-with-context"></span><span id="playing-with-context-objects"></span><span id="playing-with-context"></span><h2>使用 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 对象<a class="headerlink" href="#playing-with-context-objects" title="永久链接至标题">¶</a></h2>
<p>大多数情况下，你会通过向 <code class="docutils literal notranslate"><span class="pre">Context()</span></code> 传递一个完全填充的字典来实例化 <a class="reference internal" href="#django.template.Context" title="django.template.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> 对象。但是一旦实例化了 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 对象，你也可以使用标准的字典语法从它中添加和删除项目：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">Context</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><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>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;bar&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">del</span> <span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">KeyError</span>: <span class="n">&#39;foo&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;newvariable&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;hello&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;newvariable&#39;</span><span class="p">]</span>
<span class="go">&#39;hello&#39;</span>
</pre></div>
</div>
<dl class="method">
<dt id="django.template.Context.get">
<code class="descclassname">Context.</code><code class="descname">get</code>(<em>key</em>, <em>otherwise=None</em>)<a class="headerlink" href="#django.template.Context.get" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <code class="docutils literal notranslate"><span class="pre">key</span></code> 在上下文中，返回 <code class="docutils literal notranslate"><span class="pre">key</span></code> 的值，否则返回 <code class="docutils literal notranslate"><span class="pre">otherwise</span></code>。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.Context.setdefault">
<code class="descclassname">Context.</code><code class="descname">setdefault</code>(<em>key</em>, <em>default=None</em>)<a class="headerlink" href="#django.template.Context.setdefault" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <code class="docutils literal notranslate"><span class="pre">key</span></code> 在上下文中，则返回其值。否则用 <code class="docutils literal notranslate"><span class="pre">default</span></code> 值插入 <code class="docutils literal notranslate"><span class="pre">key</span></code> 并返回 <code class="docutils literal notranslate"><span class="pre">default</span></code>。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.Context.pop">
<code class="descclassname">Context.</code><code class="descname">pop</code>()<a class="headerlink" href="#django.template.Context.pop" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<dl class="method">
<dt id="django.template.Context.push">
<code class="descclassname">Context.</code><code class="descname">push</code>()<a class="headerlink" href="#django.template.Context.push" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<dl class="exception">
<dt id="django.template.ContextPopException">
<em class="property">exception </em><code class="descname">ContextPopException</code><a class="headerlink" href="#django.template.ContextPopException" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">Context</span></code> 对象是一个栈。也就是说，你可以 <code class="docutils literal notranslate"><span class="pre">push()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">pop()</span></code> 它。如果你 <code class="docutils literal notranslate"><span class="pre">pop()</span></code> 太多，它会引发 <code class="docutils literal notranslate"><span class="pre">django.template.ContextPopException</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">push</span><span class="p">()</span>
<span class="go">{}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;second level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;second level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="go">{&#39;foo&#39;: &#39;second level&#39;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;overwritten&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;overwritten&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">ContextPopException</span>
</pre></div>
</div>
<p>你也可以使用 <code class="docutils literal notranslate"><span class="pre">push()</span></code> 作为上下文管理器，以确保匹配的 <code class="docutils literal notranslate"><span class="pre">pop()</span></code> 被调用。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">with</span> <span class="n">c</span><span class="o">.</span><span class="n">push</span><span class="p">():</span>
<span class="gp">... </span>    <span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;second level&#39;</span>
<span class="gp">... </span>    <span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;second level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;first level&#39;</span>
</pre></div>
</div>
<p>传递给 <code class="docutils literal notranslate"><span class="pre">push()</span></code> 的所有参数都将传递给 <code class="docutils literal notranslate"><span class="pre">dict</span></code> 构造函数，用于建立新的上下文层次。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">with</span> <span class="n">c</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">foo</span><span class="o">=</span><span class="s1">&#39;second level&#39;</span><span class="p">):</span>
<span class="gp">... </span>    <span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;second level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;first level&#39;</span>
</pre></div>
</div>
<dl class="method">
<dt id="django.template.Context.update">
<code class="descclassname">Context.</code><code class="descname">update</code>(<em>other_dict</em>)<a class="headerlink" href="#django.template.Context.update" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>除了 <code class="docutils literal notranslate"><span class="pre">push()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">pop()</span></code> 之外，<code class="docutils literal notranslate"><span class="pre">Context</span></code> 对象还定义了一个 <code class="docutils literal notranslate"><span class="pre">update()</span></code> 方法。它的工作原理与 <code class="docutils literal notranslate"><span class="pre">push()</span></code> 类似，但它接受一个字典作为参数，并将该字典推到栈上，而不是空的。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;foo&#39;</span><span class="p">:</span> <span class="s1">&#39;updated&#39;</span><span class="p">})</span>
<span class="go">{&#39;foo&#39;: &#39;updated&#39;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;updated&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="go">{&#39;foo&#39;: &#39;updated&#39;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;first level&#39;</span>
</pre></div>
</div>
<p>像 <code class="docutils literal notranslate"><span class="pre">push()</span></code> 一样，你可以使用 <code class="docutils literal notranslate"><span class="pre">update()</span></code> 作为上下文管理器，以确保调用匹配的 <code class="docutils literal notranslate"><span class="pre">pop()</span></code>。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">with</span> <span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;foo&#39;</span><span class="p">:</span> <span class="s1">&#39;second level&#39;</span><span class="p">}):</span>
<span class="gp">... </span>    <span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;second level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span>
<span class="go">&#39;first level&#39;</span>
</pre></div>
</div>
<p>在 <a class="reference internal" href="../../howto/custom-template-tags.html#howto-writing-custom-template-tags"><span class="std std-ref">一些自定义模板标签</span></a> 中，使用 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 作为栈是很方便的。</p>
<dl class="method">
<dt id="django.template.Context.flatten">
<code class="descclassname">Context.</code><code class="descname">flatten</code>()<a class="headerlink" href="#django.template.Context.flatten" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>使用 <code class="docutils literal notranslate"><span class="pre">flatten()</span></code> 方法，你可以得到整个 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 堆栈作为一个字典，包括内置的变量。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;bar&#39;</span><span class="p">:</span> <span class="s1">&#39;second level&#39;</span><span class="p">})</span>
<span class="go">{&#39;bar&#39;: &#39;second level&#39;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">flatten</span><span class="p">()</span>
<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>
</pre></div>
</div>
<p>内部还使用 <code class="docutils literal notranslate"><span class="pre">flatten()</span></code> 方法使 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 对象具有可比性。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">c1</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c1</span><span class="p">[</span><span class="s1">&#39;foo&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;first level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c1</span><span class="p">[</span><span class="s1">&#39;bar&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;second level&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c2</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c2</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;bar&#39;</span><span class="p">:</span> <span class="s1">&#39;second level&#39;</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span><span class="p">:</span> <span class="s1">&#39;first level&#39;</span><span class="p">})</span>
<span class="go">{&#39;foo&#39;: &#39;first level&#39;, &#39;bar&#39;: &#39;second level&#39;}</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c1</span> <span class="o">==</span> <span class="n">c2</span>
<span class="go">True</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">flatten()</span></code> 的结果在单元测试中可以用来比较 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 和 <code class="docutils literal notranslate"><span class="pre">dict</span></code>：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ContextTest</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
    <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>
        <span class="n">c1</span> <span class="o">=</span> <span class="n">Context</span><span class="p">()</span>
        <span class="n">c1</span><span class="p">[</span><span class="s1">&#39;update&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;value&#39;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">c1</span><span class="o">.</span><span class="n">flatten</span><span class="p">(),</span> <span class="p">{</span>
            <span class="s1">&#39;True&#39;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
            <span class="s1">&#39;None&#39;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
            <span class="s1">&#39;False&#39;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
            <span class="s1">&#39;update&#39;</span><span class="p">:</span> <span class="s1">&#39;value&#39;</span><span class="p">,</span>
        <span class="p">})</span>
</pre></div>
</div>
<div class="section" id="s-using-requestcontext">
<span id="s-subclassing-context-requestcontext"></span><span id="using-requestcontext"></span><span id="subclassing-context-requestcontext"></span><h3>使用 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code><a class="headerlink" href="#using-requestcontext" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="django.template.RequestContext">
<em class="property">class </em><code class="descname">RequestContext</code>(<em>request</em>, <em>dict_=None</em>, <em>processors=None</em>)<a class="headerlink" href="#django.template.RequestContext" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>Django 有一个特殊的 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 类，<code class="docutils literal notranslate"><span class="pre">django.template.RequestContext</span></code>，它的作用与普通的 <code class="docutils literal notranslate"><span class="pre">django.template.Context</span></code> 略有不同。第一个不同是它以一个 <a class="reference internal" href="../request-response.html#django.http.HttpRequest" title="django.http.HttpRequest"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpRequest</span></code></a> 作为它的第一个参数。例如：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">c</span> <span class="o">=</span> <span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="p">{</span>
    <span class="s1">&#39;foo&#39;</span><span class="p">:</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span>
<span class="p">})</span>
</pre></div>
</div>
<p>第二个区别是，它根据引擎的 <code class="docutils literal notranslate"><span class="pre">context_processors</span></code> 配置选项，自动给上下文填充一些变量。</p>
<p><code class="docutils literal notranslate"><span class="pre">context_processors</span></code> 选项是一个可调用的列表——称为 <strong>上下文处理器</strong>——它将一个请求对象作为参数，并返回一个要合并到上下文中的项目字典。在默认生成的配置文件中，默认模板引擎包含以下上下文处理器：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span>
    <span class="s1">&#39;django.template.context_processors.debug&#39;</span><span class="p">,</span>
    <span class="s1">&#39;django.template.context_processors.request&#39;</span><span class="p">,</span>
    <span class="s1">&#39;django.contrib.auth.context_processors.auth&#39;</span><span class="p">,</span>
    <span class="s1">&#39;django.contrib.messages.context_processors.messages&#39;</span><span class="p">,</span>
<span class="p">]</span>
</pre></div>
</div>
<p>除此以外，<a class="reference internal" href="#django.template.RequestContext" title="django.template.RequestContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">RequestContext</span></code></a> 总是启用 <code class="docutils literal notranslate"><span class="pre">'django.template.context_processors.csrf'</span></code>。 这是管理和其他 contrib 应用所需要的安全相关的上下文处理器，为了防止意外的错误配置，特意将其硬编码进去，不能在 <code class="docutils literal notranslate"><span class="pre">context_processors</span></code> 选项中关闭。</p>
<p>每个处理器都是按顺序应用的。这意味着，如果一个处理器向上下文添加了一个变量，而第二个处理器添加了一个同名的变量，第二个处理器将覆盖第一个处理器。下面解释默认的处理器。</p>
<div class="admonition-when-context-processors-are-applied admonition">
<p class="first admonition-title">当应用上下文处理器时</p>
<p>上下文处理器是应用在上下文数据之上的。这意味着上下文处理器可能会覆盖你提供给 <a class="reference internal" href="#django.template.Context" title="django.template.Context"><code class="xref py py-class docutils literal notranslate"><span class="pre">Context</span></code></a> 或 <a class="reference internal" href="#django.template.RequestContext" title="django.template.RequestContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">RequestContext</span></code></a> 的变量，所以要注意避免变量名与上下文处理器提供的变量名重叠。</p>
<p>如果你想让上下文数据优先于上下文处理器，请使用以下模式：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">RequestContext</span>

<span class="n">request_context</span> <span class="o">=</span> <span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">request_context</span><span class="o">.</span><span class="n">push</span><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>
</pre></div>
</div>
<p class="last">Django 这样做是为了让上下文数据覆盖 API 中的上下文处理器，如 <a class="reference internal" href="../../topics/http/shortcuts.html#django.shortcuts.render" title="django.shortcuts.render"><code class="xref py py-func docutils literal notranslate"><span class="pre">render()</span></code></a> 和 <a class="reference internal" href="../template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><code class="xref py py-class docutils literal notranslate"><span class="pre">TemplateResponse</span></code></a>。</p>
</div>
<p>此外，你还可以使用可选的第三个位置参数 <code class="docutils literal notranslate"><span class="pre">processors</span></code>，给 <a class="reference internal" href="#django.template.RequestContext" title="django.template.RequestContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">RequestContext</span></code></a> 一个额外的处理器列表。在这个例子中， <a class="reference internal" href="#django.template.RequestContext" title="django.template.RequestContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">RequestContext</span></code></a> 实例得到一个 <code class="docutils literal notranslate"><span class="pre">ip_address</span></code> 变量：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="kn">from</span> <span class="nn">django.template</span> <span class="kn">import</span> <span class="n">RequestContext</span><span class="p">,</span> <span class="n">Template</span>

<span class="k">def</span> <span class="nf">ip_address_processor</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">{</span><span class="s1">&#39;ip_address&#39;</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">META</span><span class="p">[</span><span class="s1">&#39;REMOTE_ADDR&#39;</span><span class="p">]}</span>

<span class="k">def</span> <span class="nf">client_ip_view</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s1">&#39;{{ title }}: {{ ip_address }}&#39;</span><span class="p">)</span>
    <span class="n">context</span> <span class="o">=</span> <span class="n">RequestContext</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="p">{</span>
        <span class="s1">&#39;title&#39;</span><span class="p">:</span> <span class="s1">&#39;Your IP Address&#39;</span><span class="p">,</span>
    <span class="p">},</span> <span class="p">[</span><span class="n">ip_address_processor</span><span class="p">])</span>
    <span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>
</pre></div>
</div>
</div>
<div class="section" id="s-built-in-template-context-processors">
<span id="s-context-processors"></span><span id="built-in-template-context-processors"></span><span id="context-processors"></span><h3>内置模板上下文处理器<a class="headerlink" href="#built-in-template-context-processors" title="永久链接至标题">¶</a></h3>
<p>下面是每个内置处理器的作用：</p>
<div class="section" id="s-django-contrib-auth-context-processors-auth">
<span id="django-contrib-auth-context-processors-auth"></span><h4><code class="docutils literal notranslate"><span class="pre">django.contrib.auth.context_processors.auth</span></code><a class="headerlink" href="#django-contrib-auth-context-processors-auth" title="永久链接至标题">¶</a></h4>
<dl class="function">
<dt id="django.contrib.auth.context_processors.auth">
<code class="descname">auth</code>()<a class="headerlink" href="#django.contrib.auth.context_processors.auth" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果启用了这个处理器，每一个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含这些变量：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">user</span></code> —— 代表当前登录用户的 <code class="docutils literal notranslate"><span class="pre">auth.User</span></code> 实例（如果客户端没有登录，则为 <code class="docutils literal notranslate"><span class="pre">AnonymousUser</span></code> 实例）。</li>
<li><code class="docutils literal notranslate"><span class="pre">perms</span></code> —— <code class="docutils literal notranslate"><span class="pre">django.contrib.uth.context_processors.PermWrapper</span></code> 的实例，表示当前登录用户拥有的权限。</li>
</ul>
</div>
<div class="section" id="s-django-template-context-processors-debug">
<span id="django-template-context-processors-debug"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.debug</span></code><a class="headerlink" href="#django-template-context-processors-debug" title="永久链接至标题">¶</a></h4>
<dl class="function">
<dt id="django.template.context_processors.debug">
<code class="descname">debug</code>()<a class="headerlink" href="#django.template.context_processors.debug" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果启用了这个处理器，每一个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含这两个变量——但前提是你的 <a class="reference internal" href="../settings.html#std:setting-DEBUG"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DEBUG</span></code></a> 设置为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，并且请求的 IP 地址（<code class="docutils literal notranslate"><span class="pre">request.META['REMOTE_ADDR']</span></code>）在 <a class="reference internal" href="../settings.html#std:setting-INTERNAL_IPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INTERNAL_IPS</span></code></a> 配置中：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">debug</span></code> —— <code class="docutils literal notranslate"><span class="pre">True</span></code>。你可以在模板中使用它来测试你是否处于 <a class="reference internal" href="../settings.html#std:setting-DEBUG"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DEBUG</span></code></a> 模式。</li>
<li><code class="docutils literal notranslate"><span class="pre">sql_queries</span></code> —— <code class="docutils literal notranslate"><span class="pre">{'sql':</span> <span class="pre">...,</span> <span class="pre">'time':</span> <span class="pre">...}</span></code> 字典的列表，表示在请求过程中迄今为止发生的每一个 SQL 查询，以及花费的时间。这个列表是按照数据库别名，然后按照查询的顺序排列的。它是在访问时惰性生成的。</li>
</ul>
</div>
<div class="section" id="s-django-template-context-processors-i18n">
<span id="django-template-context-processors-i18n"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.i18n</span></code><a class="headerlink" href="#django-template-context-processors-i18n" title="永久链接至标题">¶</a></h4>
<dl class="function">
<dt id="django.template.context_processors.i18n">
<code class="descname">i18n</code>()<a class="headerlink" href="#django.template.context_processors.i18n" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果启用了这个处理器，每一个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含这些变量：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">LANGUAGES</span></code> —— <a class="reference internal" href="../settings.html#std:setting-LANGUAGES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">LANGUAGES</span></code></a> 配置值。</li>
<li><code class="docutils literal notranslate"><span class="pre">LANGUAGE_BIDI</span></code> —— <code class="docutils literal notranslate"><span class="pre">True</span></code> 如果当前语言是从右到左的语言，如希伯来语、阿拉伯语。<code class="docutils literal notranslate"><span class="pre">False</span></code> 如果是从左到右的语言，如英语、法语、德语。</li>
<li><code class="docutils literal notranslate"><span class="pre">LANGUAGE_CODE</span></code> —— <code class="docutils literal notranslate"><span class="pre">request.LANGUAGE_CODE</span></code>，如果存在的话。否则，使用 <a class="reference internal" href="../settings.html#std:setting-LANGUAGE_CODE"><code class="xref std std-setting docutils literal notranslate"><span class="pre">LANGUAGE_CODE</span></code></a> 配置的值。</li>
</ul>
<p>请参阅 <a class="reference internal" href="../../topics/i18n/translation.html#i18n-template-tags"><span class="std std-ref">i18n 模板标签</span></a>，了解产生相同值的模板标签。</p>
</div>
<div class="section" id="s-django-template-context-processors-media">
<span id="django-template-context-processors-media"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.media</span></code><a class="headerlink" href="#django-template-context-processors-media" title="永久链接至标题">¶</a></h4>
<p>如果启用了这个处理器，每一个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含一个变量 <code class="docutils literal notranslate"><span class="pre">MEDIA_URL</span></code>，提供 <a class="reference internal" href="../settings.html#std:setting-MEDIA_URL"><code class="xref std std-setting docutils literal notranslate"><span class="pre">MEDIA_URL</span></code></a> 配置的值。</p>
</div>
<div class="section" id="s-django-template-context-processors-static">
<span id="django-template-context-processors-static"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.static</span></code><a class="headerlink" href="#django-template-context-processors-static" title="永久链接至标题">¶</a></h4>
<dl class="function">
<dt id="django.template.context_processors.static">
<code class="descname">static</code>()<a class="headerlink" href="#django.template.context_processors.static" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果启用了这个处理器，每个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含一个变量 <code class="docutils literal notranslate"><span class="pre">STATIC_URL</span></code>，提供 <a class="reference internal" href="../settings.html#std:setting-STATIC_URL"><code class="xref std std-setting docutils literal notranslate"><span class="pre">STATIC_URL</span></code></a> 配置的值。</p>
</div>
<div class="section" id="s-django-template-context-processors-csrf">
<span id="django-template-context-processors-csrf"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.csrf</span></code><a class="headerlink" href="#django-template-context-processors-csrf" title="永久链接至标题">¶</a></h4>
<p>该处理器添加了 <a class="reference internal" href="builtins.html#std:templatetag-csrf_token"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">csrf_token</span></code></a> 模板标签所需的令牌，以防止 <a class="reference internal" href="../csrf.html"><span class="doc">跨站点伪造请求</span></a>。</p>
</div>
<div class="section" id="s-django-template-context-processors-request">
<span id="django-template-context-processors-request"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.request</span></code><a class="headerlink" href="#django-template-context-processors-request" title="永久链接至标题">¶</a></h4>
<p>如果启用了这个处理器，每个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含一个变量 <code class="docutils literal notranslate"><span class="pre">request</span></code>，就是当前的 <a class="reference internal" href="../request-response.html#django.http.HttpRequest" title="django.http.HttpRequest"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpRequest</span></code></a>。</p>
</div>
<div class="section" id="s-django-template-context-processors-tz">
<span id="django-template-context-processors-tz"></span><h4><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.tz</span></code><a class="headerlink" href="#django-template-context-processors-tz" title="永久链接至标题">¶</a></h4>
<dl class="function">
<dt id="django.template.context_processors.tz">
<code class="descname">tz</code>()<a class="headerlink" href="#django.template.context_processors.tz" title="永久链接至目标">¶</a></dt>
<dd></dd></dl>

<p>如果启用了这个处理器，每个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 将包含一个变量 <code class="docutils literal notranslate"><span class="pre">TIME_ZONE</span></code>，提供当前活动时区的名称。</p>
</div>
<div class="section" id="s-django-contrib-messages-context-processors-messages">
<span id="django-contrib-messages-context-processors-messages"></span><h4><code class="docutils literal notranslate"><span class="pre">django.contrib.messages.context_processors.messages</span></code><a class="headerlink" href="#django-contrib-messages-context-processors-messages" title="永久链接至标题">¶</a></h4>
<p>如果启用了这个处理器，每一个 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code> 都会包含这两个变量：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">messages</span></code> —— 通过 <a class="reference internal" href="../contrib/messages.html"><span class="doc">消息框架</span></a> 设置的信息列表（字符串）。</li>
<li><code class="docutils literal notranslate"><span class="pre">DEFAULT_MESSAGE_LEVELS</span></code> —— 信息级别名称与 <a class="reference internal" href="../contrib/messages.html#message-level-constants"><span class="std std-ref">其数值</span></a> 的映射。</li>
</ul>
</div>
</div>
<div class="section" id="s-writing-your-own-context-processors">
<span id="writing-your-own-context-processors"></span><h3>编写你自己的上下文处理器<a class="headerlink" href="#writing-your-own-context-processors" title="永久链接至标题">¶</a></h3>
<p>A context processor has a simple interface: It's a Python function that takes
one argument, an <a class="reference internal" href="../request-response.html#django.http.HttpRequest" title="django.http.HttpRequest"><code class="xref py py-class docutils literal notranslate"><span class="pre">HttpRequest</span></code></a> object, and returns a
dictionary that gets added to the template context.</p>
<p>For example, to add the <a class="reference internal" href="../settings.html#std:setting-DEFAULT_FROM_EMAIL"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DEFAULT_FROM_EMAIL</span></code></a> setting to every
context:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>

<span class="k">def</span> <span class="nf">from_email</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="s2">&quot;DEFAULT_FROM_EMAIL&quot;</span><span class="p">:</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_FROM_EMAIL</span><span class="p">,</span>
    <span class="p">}</span>
</pre></div>
</div>
<p>自定义上下文处理器可以存在于你的代码库中的任何地方。Django 只关心你的自定义上下文处理器是否被你的 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">TEMPLATES</span></code></a> 配置中的 <code class="docutils literal notranslate"><span class="pre">'context_processors'</span></code> 选项所指向，如果你直接使用的话，则是 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a> 的 <code class="docutils literal notranslate"><span class="pre">context_processors</span></code> 参数。</p>
</div>
</div>
<div class="section" id="s-loading-templates">
<span id="loading-templates"></span><h2>加载模板<a class="headerlink" href="#loading-templates" title="永久链接至标题">¶</a></h2>
<p>一般来说，你会把模板存储在文件系统的文件中，而不是自己使用低级的 <a class="reference internal" href="../../topics/templates.html#module-django.template" title="django.template: Django's template system"><code class="xref py py-class docutils literal notranslate"><span class="pre">template</span></code></a> API。将模板保存在指定的 <strong>template 目录</strong> 中。</p>
<p>Django 会在很多地方搜索模板目录，这取决于你的模板加载设置（见下面的“加载器类型”），但最基本的指定模板目录的方法是使用 <code class="xref std std-setting docutils literal notranslate"><span class="pre">DIRS</span></code> 选项。</p>
<div class="section" id="s-the-dirs-option">
<span id="the-dirs-option"></span><h3><a class="reference internal" href="../settings.html#std:setting-TEMPLATES-DIRS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DIRS</span></code></a> 选项<a class="headerlink" href="#the-dirs-option" title="永久链接至标题">¶</a></h3>
<p>通过使用配置文件中的 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">TEMPLATES</span></code></a> 配置中的 <code class="xref std std-setting docutils literal notranslate"><span class="pre">DIRS</span></code> 选项来告诉 Django 你的模板目录是什么，或者使用 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a> 中的 <code class="docutils literal notranslate"><span class="pre">dirs</span></code> 参数。这应该被设置为一个字符串列表，其中包含你的模板目录的完整路径：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TEMPLATES</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">{</span>
        <span class="s1">&#39;BACKEND&#39;</span><span class="p">:</span> <span class="s1">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class="p">,</span>
        <span class="s1">&#39;DIRS&#39;</span><span class="p">:</span> <span class="p">[</span>
            <span class="s1">&#39;/home/html/templates/lawrence.com&#39;</span><span class="p">,</span>
            <span class="s1">&#39;/home/html/templates/default&#39;</span><span class="p">,</span>
        <span class="p">],</span>
    <span class="p">},</span>
<span class="p">]</span>
</pre></div>
</div>
<p>你的模板可以放在任何你想去的地方，只要这些目录和模板可以被 Web 服务器读取。它们可以有任何你想要的扩展名，如 <code class="docutils literal notranslate"><span class="pre">.html</span></code> 或 <code class="docutils literal notranslate"><span class="pre">.txt</span></code>，或者它们可以没有任何扩展名。</p>
<p>请注意，这些路径应该使用 Unix 风格的斜线，即使在 Windows 上也是如此。</p>
</div>
<div class="section" id="s-loader-types">
<span id="s-template-loaders"></span><span id="loader-types"></span><span id="template-loaders"></span><h3>加载器类型<a class="headerlink" href="#loader-types" title="永久链接至标题">¶</a></h3>
<p>默认情况下，Django 使用的是基于文件系统的模板加载器，但 Django 自带了一些其他的模板加载器，它们知道如何从其他来源加载模板。</p>
<p>其他一些加载器默认是禁用的，但是你可以通过在 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES"><code class="xref std std-setting docutils literal notranslate"><span class="pre">TEMPLATES</span></code></a> 配置中为你的 <code class="docutils literal notranslate"><span class="pre">DjangoTemplates</span></code> 后端添加一个 <code class="docutils literal notranslate"><span class="pre">'loaders'</span></code> 选项来激活它们，或者向 <a class="reference internal" href="#django.template.Engine" title="django.template.Engine"><code class="xref py py-class docutils literal notranslate"><span class="pre">Engine</span></code></a> 传递一个 <code class="docutils literal notranslate"><span class="pre">loaders</span></code> 参数。<code class="docutils literal notranslate"><span class="pre">loaders</span></code> 应该是一个字符串或元组的列表，每个元组代表一个模板加载器类。下面是 Django 自带的模板加载器。</p>
<p><code class="docutils literal notranslate"><span class="pre">django.template.loaders.filesystem.Loader</span></code></p>
<dl class="class">
<dt id="django.template.loaders.filesystem.Loader">
<em class="property">class </em><code class="descclassname">filesystem.</code><code class="descname">Loader</code><a class="headerlink" href="#django.template.loaders.filesystem.Loader" title="永久链接至目标">¶</a></dt>
<dd><p>根据 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES-DIRS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DIRS</span></code></a> 从文件系统加载模板。</p>
<p>这个加载器默认是启用的。然而，它不会找到任何模板，直到你将 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES-DIRS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DIRS</span></code></a> 设置为非空列表：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TEMPLATES</span> <span class="o">=</span> <span class="p">[{</span>
    <span class="s1">&#39;BACKEND&#39;</span><span class="p">:</span> <span class="s1">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class="p">,</span>
    <span class="s1">&#39;DIRS&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">BASE_DIR</span> <span class="o">/</span> <span class="s1">&#39;templates&#39;</span><span class="p">],</span>
<span class="p">}]</span>
</pre></div>
</div>
<p>你也可以覆盖 <code class="docutils literal notranslate"><span class="pre">'DIRS'</span></code>，为特定的文件系统加载器指定特定的目录：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TEMPLATES</span> <span class="o">=</span> <span class="p">[{</span>
    <span class="s1">&#39;BACKEND&#39;</span><span class="p">:</span> <span class="s1">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class="p">,</span>
    <span class="s1">&#39;OPTIONS&#39;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s1">&#39;loaders&#39;</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">(</span>
                <span class="s1">&#39;django.template.loaders.filesystem.Loader&#39;</span><span class="p">,</span>
                <span class="p">[</span><span class="n">BASE_DIR</span> <span class="o">/</span> <span class="s1">&#39;templates&#39;</span><span class="p">],</span>
            <span class="p">),</span>
        <span class="p">],</span>
    <span class="p">},</span>
<span class="p">}]</span>
</pre></div>
</div>
</dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">django.template.loaders.app_directories.Loader</span></code></p>
<dl class="class">
<dt id="django.template.loaders.app_directories.Loader">
<em class="property">class </em><code class="descclassname">app_directories.</code><code class="descname">Loader</code><a class="headerlink" href="#django.template.loaders.app_directories.Loader" title="永久链接至目标">¶</a></dt>
<dd><p>从文件系统中加载 Django 应用的模板。对于 <a class="reference internal" href="../settings.html#std:setting-INSTALLED_APPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code></a> 中的每个应用，加载器会寻找一个 <code class="docutils literal notranslate"><span class="pre">templates</span></code> 子目录。如果该目录存在，Django 就会在其中寻找模板。</p>
<p>这意味着你可以将模板与你的各个应用一起存储。这也有助于分发带有默认模板的 Django 应用。</p>
<p>例如，对于这个配置：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">INSTALLED_APPS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;myproject.polls&#39;</span><span class="p">,</span> <span class="s1">&#39;myproject.music&#39;</span><span class="p">]</span>
</pre></div>
</div>
<p>...然后 <code class="docutils literal notranslate"><span class="pre">get_template('foo.html')</span></code> 将在这些目录中按这个顺序查找 <code class="docutils literal notranslate"><span class="pre">foo.html</span></code>：</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">/path/to/myproject/polls/templates/</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">/path/to/myproject/music/templates/</span></code></li>
</ul>
<p>...会用它最先找到的那个：</p>
<p><a class="reference internal" href="../settings.html#std:setting-INSTALLED_APPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code></a> 的顺序很重要！例如，如果你想自定义 Django 管理，你可能会选择覆盖标准 <code class="docutils literal notranslate"><span class="pre">django.contrib.admin</span></code> 的 <code class="docutils literal notranslate"><span class="pre">admin/base_site.html</span></code> 模板，，用你自己 <code class="docutils literal notranslate"><span class="pre">myproject.polls</span></code> 中的 <code class="docutils literal notranslate"><span class="pre">admin/base_site.html</span></code>。然后你必须确保你的 <code class="docutils literal notranslate"><span class="pre">myproject.polls</span></code> 在 <a class="reference internal" href="../settings.html#std:setting-INSTALLED_APPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code></a> 中在 <code class="docutils literal notranslate"><span class="pre">django.contrib.admin</span></code> <em>之前</em>，否则 <code class="docutils literal notranslate"><span class="pre">django.contrib.admin</span></code> 的会先被加载，你的会被忽略。</p>
<p>请注意，加载器在第一次运行时进行了优化：它缓存了一个列表，显示哪些 <a class="reference internal" href="../settings.html#std:setting-INSTALLED_APPS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">INSTALLED_APPS</span></code></a> 包有一个 <code class="docutils literal notranslate"><span class="pre">templates</span></code> 子目录。</p>
<p>你可以通过设置 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES-APP_DIRS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">APP_DIRS</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 来启用该加载器：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TEMPLATES</span> <span class="o">=</span> <span class="p">[{</span>
    <span class="s1">&#39;BACKEND&#39;</span><span class="p">:</span> <span class="s1">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class="p">,</span>
    <span class="s1">&#39;APP_DIRS&#39;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="p">}]</span>
</pre></div>
</div>
</dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">django.template.loaders.cached.Loader</span></code></p>
<dl class="class">
<dt id="django.template.loaders.cached.Loader">
<em class="property">class </em><code class="descclassname">cached.</code><code class="descname">Loader</code><a class="headerlink" href="#django.template.loaders.cached.Loader" title="永久链接至目标">¶</a></dt>
<dd><p>默认情况下（当 <a class="reference internal" href="../settings.html#std:setting-DEBUG"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DEBUG</span></code></a> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时），模板系统会在每次渲染模板时读取并编译模板。虽然 Django 模板系统的速度相当快，但读取和编译模板所带来的开销也会增加。</p>
<p>你可以用其他加载器的列表来配置缓存的模板加载器，它应该对这些加载器进行封装。当第一次遇到未知模板时，封装的加载器被用来定位它们。然后，缓存加载器将编译后的 <code class="docutils literal notranslate"><span class="pre">Template</span></code> 存储在内存中。缓存的 <code class="docutils literal notranslate"><span class="pre">Template</span></code> 实例会被返回，供后续加载同一模板的请求使用。</p>
<p>如果 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES-OPTIONS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">OPTIONS['loaders']</span></code></a> 没有指定，并且 <a class="reference internal" href="../settings.html#std:setting-TEMPLATES-OPTIONS"><code class="xref std std-setting docutils literal notranslate"><span class="pre">OPTIONS['debug']</span></code></a> 是 <code class="docutils literal notranslate"><span class="pre">False</span></code> （后一个选项默认为 <a class="reference internal" href="../settings.html#std:setting-DEBUG"><code class="xref std std-setting docutils literal notranslate"><span class="pre">DEBUG</span></code></a> 的值），这个加载器就会自动启用。</p>
<p>你也可以使用一些自定义模板加载器启用模板缓存，使用这样的设置：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TEMPLATES</span> <span class="o">=</span> <span class="p">[{</span>
    <span class="s1">&#39;BACKEND&#39;</span><span class="p">:</span> <span class="s1">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class="p">,</span>
    <span class="s1">&#39;DIRS&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">BASE_DIR</span> <span class="o">/</span> <span class="s1">&#39;templates&#39;</span><span class="p">],</span>
    <span class="s1">&#39;OPTIONS&#39;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s1">&#39;loaders&#39;</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">(</span><span class="s1">&#39;django.template.loaders.cached.Loader&#39;</span><span class="p">,</span> <span class="p">[</span>
                <span class="s1">&#39;django.template.loaders.filesystem.Loader&#39;</span><span class="p">,</span>
                <span class="s1">&#39;django.template.loaders.app_directories.Loader&#39;</span><span class="p">,</span>
                <span class="s1">&#39;path.to.custom.Loader&#39;</span><span class="p">,</span>
            <span class="p">]),</span>
        <span class="p">],</span>
    <span class="p">},</span>
<span class="p">}]</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">所有内置的 Django 模板标签都可以安全地使用缓存加载器，但如果你使用的是来自第三方包的自定义模板标签，或者你自己编写的模板标签，你应该确保每个标签的“节点”实现是线程安全的。更多信息，请参见 <a class="reference internal" href="../../howto/custom-template-tags.html#template-tag-thread-safety"><span class="std std-ref">模板标签线程安全注意事项</span></a>。</p>
</div>
</dd></dl>

<p><code class="docutils literal notranslate"><span class="pre">django.template.loaders.locmem.Loader</span></code></p>
<dl class="class">
<dt id="django.template.loaders.locmem.Loader">
<em class="property">class </em><code class="descclassname">locmem.</code><code class="descname">Loader</code><a class="headerlink" href="#django.template.loaders.locmem.Loader" title="永久链接至目标">¶</a></dt>
<dd><p>从 Python 字典中加载模板。这对测试很有用。</p>
<p>该加载器将模板字典作为其第一个参数：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">TEMPLATES</span> <span class="o">=</span> <span class="p">[{</span>
    <span class="s1">&#39;BACKEND&#39;</span><span class="p">:</span> <span class="s1">&#39;django.template.backends.django.DjangoTemplates&#39;</span><span class="p">,</span>
    <span class="s1">&#39;OPTIONS&#39;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s1">&#39;loaders&#39;</span><span class="p">:</span> <span class="p">[</span>
            <span class="p">(</span><span class="s1">&#39;django.template.loaders.locmem.Loader&#39;</span><span class="p">,</span> <span class="p">{</span>
                <span class="s1">&#39;index.html&#39;</span><span class="p">:</span> <span class="s1">&#39;content here&#39;</span><span class="p">,</span>
            <span class="p">}),</span>
        <span class="p">],</span>
    <span class="p">},</span>
<span class="p">}]</span>
</pre></div>
</div>
<p>该加载器默认为禁用。</p>
</dd></dl>

<p>Django 根据 <code class="docutils literal notranslate"><span class="pre">'loaders'</span></code> 选项的顺序使用模板加载器。它使用每个加载器，直到一个加载器找到匹配的模板。</p>
</div>
</div>
<div class="section" id="s-custom-loaders">
<span id="s-custom-template-loaders"></span><span id="custom-loaders"></span><span id="custom-template-loaders"></span><h2>自定义加载器<a class="headerlink" href="#custom-loaders" title="永久链接至标题">¶</a></h2>
<p>可以使用自定义模板加载器从其他来源加载模板。自定义 <code class="docutils literal notranslate"><span class="pre">Loader</span></code> 类应该继承 <code class="docutils literal notranslate"><span class="pre">django.template.loaders.base.Loader</span></code> 并定义 <code class="docutils literal notranslate"><span class="pre">get_contents()</span></code> 和 <code class="docutils literal notranslate"><span class="pre">get_template_sources()</span></code> 方法。</p>
<div class="section" id="s-loader-methods">
<span id="loader-methods"></span><h3>加载器方法<a class="headerlink" href="#loader-methods" title="永久链接至标题">¶</a></h3>
<dl class="class">
<dt id="django.template.loaders.base.Loader">
<em class="property">class </em><code class="descname">Loader</code><a class="headerlink" href="#django.template.loaders.base.Loader" title="永久链接至目标">¶</a></dt>
<dd><p>从给定的源，如文件系统或数据库中加载模板。</p>
<dl class="method">
<dt id="django.template.loaders.base.Loader.get_template_sources">
<code class="descname">get_template_sources</code>(<em>template_name</em>)<a class="headerlink" href="#django.template.loaders.base.Loader.get_template_sources" title="永久链接至目标">¶</a></dt>
<dd><p>一个接受 <code class="docutils literal notranslate"><span class="pre">template_name</span></code> 的方法，并为每个可能的来源产生 <a class="reference internal" href="#django.template.base.Origin" title="django.template.base.Origin"><code class="xref py py-class docutils literal notranslate"><span class="pre">Origin</span></code></a> 实例。</p>
<p>例如，文件系统加载器可以接收 <code class="docutils literal notranslate"><span class="pre">'index.html'</span></code> 作为 <code class="docutils literal notranslate"><span class="pre">template_name</span></code> 参数。 这个方法将产生 <code class="docutils literal notranslate"><span class="pre">index.html</span></code> 的完整路径的起源，因为它出现在加载器查看的每个模板目录中。</p>
<p>该方法不需要验证模板是否存在于给定的路径中，但它应该确保路径是有效的。例如，文件系统加载器会确保路径位于一个有效的模板目录下。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.loaders.base.Loader.get_contents">
<code class="descname">get_contents</code>(<em>origin</em>)<a class="headerlink" href="#django.template.loaders.base.Loader.get_contents" title="永久链接至目标">¶</a></dt>
<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"><span class="pre">Origin</span></code></a> 实例的模板的内容。</p>
<p>这是一个文件系统加载器从文件系统读取内容的地方，或者一个数据库加载器从数据库读取内容的地方。如果一个匹配的模板不存在，这应该会引发一个 <a class="reference internal" href="../../topics/templates.html#django.template.TemplateDoesNotExist" title="django.template.TemplateDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TemplateDoesNotExist</span></code></a> 错误。</p>
</dd></dl>

<dl class="method">
<dt id="django.template.loaders.base.Loader.get_template">
<code class="descname">get_template</code>(<em>template_name</em>, <em>skip=None</em>)<a class="headerlink" href="#django.template.loaders.base.Loader.get_template" title="永久链接至目标">¶</a></dt>
<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"><span class="pre">get_template_sources()</span></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"><span class="pre">get_contents()</span></code></a> 的结果，为给定的 <code class="docutils literal notranslate"><span class="pre">template_name</span></code> 返回一个 <code class="docutils literal notranslate"><span class="pre">Template</span></code> 对象。这将返回第一个匹配的模板。如果没有找到模板，则会引发 <a class="reference internal" href="../../topics/templates.html#django.template.TemplateDoesNotExist" title="django.template.TemplateDoesNotExist"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TemplateDoesNotExist</span></code></a>。</p>
<p>可选的 <code class="docutils literal notranslate"><span class="pre">skip</span></code> 参数是扩展模板时要忽略的起源列表。这允许模板扩展同名的其他模板。它也用于避免递归错误。</p>
<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"><span class="pre">get_template_sources()</span></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"><span class="pre">get_contents()</span></code></a> 为自定义模板加载器就可以了。<code class="docutils literal notranslate"><span class="pre">get_template()</span></code> 通常不需要重写。</p>
</dd></dl>

</dd></dl>

<div class="admonition-building-your-own admonition">
<p class="first admonition-title">构建你自己的</p>
<p class="last">例如，请阅读 <a class="reference external" href="https://github.com/django/django/blob/main/django/template/loaders">Django 内置加载器的源代码</a>。</p>
</div>
</div>
</div>
<div class="section" id="s-template-origin">
<span id="template-origin"></span><h2>模板起源<a class="headerlink" href="#template-origin" title="永久链接至标题">¶</a></h2>
<p>模板有一个 <code class="docutils literal notranslate"><span class="pre">origin</span></code>，包含的属性取决于它们的来源。</p>
<dl class="class">
<dt id="django.template.base.Origin">
<em class="property">class </em><code class="descname">Origin</code>(<em>name</em>, <em>template_name=None</em>, <em>loader=None</em>)<a class="headerlink" href="#django.template.base.Origin" title="永久链接至目标">¶</a></dt>
<dd><dl class="attribute">
<dt id="django.template.base.Origin.name">
<code class="descname">name</code><a class="headerlink" href="#django.template.base.Origin.name" title="永久链接至目标">¶</a></dt>
<dd><p>模板加载器返回的模板路径。对于从文件系统读取的加载器，这是模板的完整路径。</p>
<p>如果模板是直接实例化的，而不是通过模板加载器，这是一个字符串值 <code class="docutils literal notranslate"><span class="pre">&lt;unknown_source&gt;</span></code>。</p>
</dd></dl>

<dl class="attribute">
<dt id="django.template.base.Origin.template_name">
<code class="descname">template_name</code><a class="headerlink" href="#django.template.base.Origin.template_name" title="永久链接至目标">¶</a></dt>
<dd><p>传入模板加载器的模板的相对路径。</p>
<p>如果模板是直接实例化的，而不是通过模板加载器，这就是 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
</dd></dl>

<dl class="attribute">
<dt id="django.template.base.Origin.loader">
<code class="descname">loader</code><a class="headerlink" href="#django.template.base.Origin.loader" title="永久链接至目标">¶</a></dt>
<dd><p>构建这个 <code class="docutils literal notranslate"><span class="pre">Origin</span></code> 的模板加载器实例。</p>
<p>如果模板是直接实例化的，而不是通过模板加载器，这就是 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
<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"><span class="pre">django.template.loaders.cached.Loader</span></code></a> 要求所有封装的加载器都要设置这个属性，通常是通过实例化 <code class="docutils literal notranslate"><span class="pre">loader=self</span></code> 的 <code class="docutils literal notranslate"><span class="pre">Origin</span></code>。</p>
</dd></dl>

</dd></dl>

</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Django 模板语言：对于 Python 开发者</a><ul>
<li><a class="reference internal" href="#overview">概况</a></li>
<li><a class="reference internal" href="#configuring-an-engine">设置引擎</a></li>
<li><a class="reference internal" href="#loading-a-template">加载模板</a></li>
<li><a class="reference internal" href="#rendering-a-context">渲染上下文</a><ul>
<li><a class="reference internal" href="#variables-and-lookups">变量和查找</a></li>
<li><a class="reference internal" href="#how-invalid-variables-are-handled">如何处理无效变量</a></li>
<li><a class="reference internal" href="#built-in-variables">内置变量</a></li>
<li><a class="reference internal" href="#limitations-with-string-literals">字符串的限制</a></li>
</ul>
</li>
<li><a class="reference internal" href="#playing-with-context-objects">使用 <code class="docutils literal notranslate"><span class="pre">Context</span></code> 对象</a><ul>
<li><a class="reference internal" href="#using-requestcontext">使用 <code class="docutils literal notranslate"><span class="pre">RequestContext</span></code></a></li>
<li><a class="reference internal" href="#built-in-template-context-processors">内置模板上下文处理器</a><ul>
<li><a class="reference internal" href="#django-contrib-auth-context-processors-auth"><code class="docutils literal notranslate"><span class="pre">django.contrib.auth.context_processors.auth</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-debug"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.debug</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-i18n"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.i18n</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-media"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.media</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-static"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.static</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-csrf"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.csrf</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-request"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.request</span></code></a></li>
<li><a class="reference internal" href="#django-template-context-processors-tz"><code class="docutils literal notranslate"><span class="pre">django.template.context_processors.tz</span></code></a></li>
<li><a class="reference internal" href="#django-contrib-messages-context-processors-messages"><code class="docutils literal notranslate"><span class="pre">django.contrib.messages.context_processors.messages</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#writing-your-own-context-processors">编写你自己的上下文处理器</a></li>
</ul>
</li>
<li><a class="reference internal" href="#loading-templates">加载模板</a><ul>
<li><a class="reference internal" href="#the-dirs-option"><code class="docutils literal notranslate"><span class="pre">DIRS</span></code> 选项</a></li>
<li><a class="reference internal" href="#loader-types">加载器类型</a></li>
</ul>
</li>
<li><a class="reference internal" href="#custom-loaders">自定义加载器</a><ul>
<li><a class="reference internal" href="#loader-methods">加载器方法</a></li>
</ul>
</li>
<li><a class="reference internal" href="#template-origin">模板起源</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="builtins.html"
                        title="上一章">内置模板标签和过滤器</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="../template-response.html"
                        title="下一章"><code class="docutils literal notranslate"><span class="pre">TemplateResponse</span></code> 和 <code class="docutils literal notranslate"><span class="pre">SimpleTemplateResponse</span></code></a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/ref/templates/api.txt"
            rel="nofollow">显示源代码</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>快速搜索</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="转向" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">12月 07, 2021</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="builtins.html" title="内置模板标签和过滤器">previous</a>
     |
    <a href="../index.html" title="API 参考" accesskey="U">up</a>
   |
    <a href="../template-response.html" title="&lt;code class=&#34;docutils literal notranslate&#34;&gt;&lt;span class=&#34;pre&#34;&gt;TemplateResponse&lt;/span&gt;&lt;/code&gt; 和 &lt;code class=&#34;docutils literal notranslate&#34;&gt;&lt;span class=&#34;pre&#34;&gt;SimpleTemplateResponse&lt;/span&gt;&lt;/code&gt;">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>