内置模板标签和过滤器

本文档描述了 Django 内置的模板标签和过滤器。如果有的话,建议你使用 自动化文档,因为它也会包含安装的任何自定义标签或过滤器的文档。

内置标签参考

autoescape

控制当前的自动转义行为。该标签以 onoff 作为参数,决定块内是否有自动转义行为。此区块以 endautoescape 结束标签关闭。

示例用法:

  1. {% autoescape on %}
  2. {{ body }}
  3. {% endautoescape %}

当自动转义生效时,从变量派生的所有内容在将结果放入输出之前都会应用 HTML 转义(但在应用任何过滤器之后)。这相当于手动对每个变量应用 escape 过滤器。

唯一的例外是已经标记为不需要转义的变量。变量可以通过填充变量的代码、应用 safeescape 过滤器,或者因为它是以前的过滤器将字符串标记为 “safe” 的结果而被标记为 “safe”。

在禁用自动转义的范围内,链式过滤器,包括 escape,可能会导致意外的(但已记录的)结果,例如以下示例:

  1. {% autoescape off %}
  2. {{ my_list|join:", "|escape }}
  3. {% endautoescape %}

上述代码将输出未经转义的 my_list 的连接元素。这是因为过滤器链序列首先在 my_list 上执行 join (由于 autoescapeoff,不对每个项目应用转义),将结果标记为安全。随后,将安全结果提供给 escape 过滤器,该过滤器不会应用第二轮转义。

为了正确地转义序列中的每个元素,请使用 escapeseq 过滤器:

  1. {% autoescape off %}
  2. {{ my_list|escapeseq|join:", " }}
  3. {% endautoescape %}

block

定义一个可以被子模板覆盖的块。更多信息请参见 模板继承

comment

忽略 {% comment %}{% endcomment %} 之间的所有内容。可以在第一个标签中插入一个可选的注释。例如,这在注释代码时很有用,可以记录代码被禁用的原因。

示例用法:

  1. <p>Rendered text with {{ pub_date|date:"c" }}</p>
  2. {% comment "Optional note" %}
  3. <p>Commented out text with {{ create_date|date:"c" }}</p>
  4. {% endcomment %}

comment 标签不能嵌套。

csrf_token

这个标签用于 CSRF 保护,如 跨站点请求伪造 的文档中所述。

cycle

每次遇到这个标记时,都会产生一个参数。第一次遇到时产生第一个参数,第二次遇到时产生第二个参数,以此类推。一旦用尽所有参数,标签就会循环到第一个参数,并再次生成它。

这个标签在循环中特别有用:

  1. {% for o in some_list %}
  2. <tr class="{% cycle 'row1' 'row2' %}">
  3. ...
  4. </tr>
  5. {% endfor %}

第一次迭代产生的 HTML 引用类 row1,第二次引用 row2,第三次再引用 row1,以此类推,每次循环迭代。

你也可以使用变量。例如,如果你有两个模板变量,rowvalue1rowvalue2,你可以像这样交替使用它们的值:

  1. {% for o in some_list %}
  2. <tr class="{% cycle rowvalue1 rowvalue2 %}">
  3. ...
  4. </tr>
  5. {% endfor %}

包含在循环中的变量将被转义。你可以使用以下方式禁用自动转义:

  1. {% for o in some_list %}
  2. <tr class="{% autoescape off %}{% cycle rowvalue1 rowvalue2 %}{% endautoescape %}">
  3. ...
  4. </tr>
  5. {% endfor %}

你可以混合使用变量和字符串:

  1. {% for o in some_list %}
  2. <tr class="{% cycle 'row1' rowvalue2 'row3' %}">
  3. ...
  4. </tr>
  5. {% endfor %}

在某些情况下,你可能希望引用循环的当前值而不前进到下一个值。要实现这一点,可以使用 “as” 给 {% cycle %} 标签起一个名称,像这样:

  1. {% cycle 'row1' 'row2' as rowcolors %}

从那时起,你可以通过将周期名称作为上下文变量来引用,在模板中的任何位置插入当前周期的当前值。如果你想独立于原始的 cycle 标记将周期移到下一个值,你可以使用另一个 cycle 标记并指定变量的名称。因此,下面的模板:

  1. <tr>
  2. <td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
  3. <td class="{{ rowcolors }}">...</td>
  4. </tr>
  5. <tr>
  6. <td class="{% cycle rowcolors %}">...</td>
  7. <td class="{{ rowcolors }}">...</td>
  8. </tr>

将会输出:

  1. <tr>
  2. <td class="row1">...</td>
  3. <td class="row1">...</td>
  4. </tr>
  5. <tr>
  6. <td class="row2">...</td>
  7. <td class="row2">...</td>
  8. </tr>

你可以在一个 cycle 标签中使用任意数量的值,用空格隔开。用单引号(')或双引号(")括起来的值被视为字符串字面,而没有引号的值被视为模板变量。

默认情况下,当你在循环标签中使用 as 关键字时,使用 {% cycle %} 来启动循环的部分将产生循环中的第一个值。如果你希望在嵌套循环或包含的模板中使用该值,这可能会成为问题。如果你只想声明循环但不产生第一个值,你可以在标签的最后加上一个 silent 关键字。例如:

  1. {% for obj in some_list %}
  2. {% cycle 'row1' 'row2' as rowcolors silent %}
  3. <tr class="{{ rowcolors }}">{% include "subtemplate.html" %}</tr>
  4. {% endfor %}

这将输出一个 <tr> 元素的列表,其 classrow1row2 之间交替出现。子模板在其上下文中可以访问 rowcolors,其值将与包围它的 <tr> 的类相匹配。如果省略 silent 关键字,row1row2 将作为普通文本在 <tr> 元素之外发出。

当在循环定义上使用静默关键字时,静默会自动应用于该特定循环标记的所有后续使用。即使第二次调用 {% cycle %} 没有指定 silent,以下模板也会输出 nothing

  1. {% cycle 'row1' 'row2' as rowcolors silent %}
  2. {% cycle rowcolors %}

你可以使用 resetcycle 标签使 {% cycle %} 标签在下次遇到时从第一个值重新开始。

debug

DEBUG 设置为 False 时,输出大量的调试信息,包括当前上下文和导入的模块。{% debug %} 在这种情况下不会输出任何内容。

extends

表示该模板扩展了一个父模板。

这个标签有两种使用方式:

  • {% extends "base.html" %} (带引号)使用字面值 "base.html" 作为要扩展的父模板的名称。
  • {% extends variable %} 使用 variable 的值。如果变量的值是一个字符串,Django 将使用这个字符串作为父模板的名称。如果变量的值是一个 Template 对象,Django 将使用该对象作为父模板。

更多内容请参见 模板继承 文档.

通常,模板名称相对于模板加载器的根目录。字符串参数也可以是以 ./../ 开头的相对路径。例如,假设以下目录结构:

  1. dir1/
  2. template.html
  3. base2.html
  4. my/
  5. base3.html
  6. base1.html

template.html 中,以下路径将是有效的:

  1. {% extends "./base2.html" %}
  2. {% extends "../base1.html" %}
  3. {% extends "./my/base3.html" %}

filter

通过一个或多个过滤器过滤块的内容。可以用管道指定多个过滤器,过滤器可以有参数,就像变量语法一样。

请注意,该块包括 filterendfilter 标签之间的 所有 文本。

示例用法:

  1. {% filter force_escape|lower %}
  2. This text will be HTML-escaped, and will appear in all lowercase.
  3. {% endfilter %}

备注

escapesafe 过滤器是不可接受的参数。取而代之的是,使用 autoescape 标签来管理模板代码块的自动转义。

firstof

输出第一个不是 false 的参数变量(即存在、不为空、不是一个错误的布尔值,也不是一个零的数值)。如果所有传递的变量都是 false,则不输出任何内容。

示例用法:

  1. {% firstof var1 var2 var3 %}

这相当于:

  1. {% if var1 %}
  2. {{ var1 }}
  3. {% elif var2 %}
  4. {{ var2 }}
  5. {% elif var3 %}
  6. {{ var3 }}
  7. {% endif %}

你还可以使用一个字面字符串作为备用值,以防传递的所有变量都为 False:

  1. {% firstof var1 var2 var3 "fallback value" %}

这个标签会自动转义变量的值。你可以使用以下方式禁用自动转义:

  1. {% autoescape off %}
  2. {% firstof var1 var2 var3 "<strong>fallback value</strong>" %}
  3. {% endautoescape %}

或者如果只有某些变量应该被转义,你可以使用:

  1. {% firstof var1 var2|safe var3 "<strong>fallback value</strong>"|safe %}

你可以使用 {% firstof var1 var2 var3 as value %} 的语法将输出结果存储在一个变量中。

for

循环遍历数组中的每个项目,并将项目作为上下文变量可用。例如,要显示提供在 athlete_list 中的运动员列表:

  1. <ul>
  2. {% for athlete in athlete_list %}
  3. <li>{{ athlete.name }}</li>
  4. {% endfor %}
  5. </ul>

你可以通过使用 {% for obj in list reversed %} 来反向循环一个列表。

如果需要循环遍历一个列表的列表,你可以将每个子列表中的值解包成单独的变量。例如,如果你的上下文包含一个名为 points 的 (x,y) 坐标列表,你可以使用以下方法输出点的列表:

  1. {% for x, y in points %}
  2. There is a point at {{ x }},{{ y }}
  3. {% endfor %}

如果需要访问字典中的项目,这也可能很有用。例如,如果你的上下文包含一个字典 data,以下内容将显示字典的键和值:

  1. {% for key, value in data.items %}
  2. {{ key }}: {{ value }}
  3. {% endfor %}

请记住,对于点运算符来说,字典键查询优先于方法查询。因此,如果 data 字典中包含一个名为 'items' 的键,data.items 将返回 data['items']` 而不是 data.items()。如果你想在模板中使用这些方法,避免添加像字典方法一样命名的键(itemsvalueskeys 等)。在 模板变量的文档 中阅读更多关于点运算符的查找顺序。

for 循环设置了一组可以在循环体内直接使用的变量:

变量名描述
forloop.counter循环计数器,表示当前循环的索引(从 1 开始)。
forloop.counter0循环计数器,表示当前循环的索引(从 0 开始)。
forloop.revcounter反向循环计数器(以最后一次循环为 1,反向计数)。
forloop.revcounter0反向循环计数器(以最后一次循环为 0,反向计数)。
forloop.first当前循环为首个循环时,该变量为 True
forloop.last当前循环为最后一个循环时,该变量为 True
forloop.parentloop在嵌套循环中,指向当前循环的上级循环

forempty

for 标签可以带有一个可选的 {% empty %} 子句,如果给定的数组为空或找不到,则显示其文本:

  1. <ul>
  2. {% for athlete in athlete_list %}
  3. <li>{{ athlete.name }}</li>
  4. {% empty %}
  5. <li>Sorry, no athletes in this list.</li>
  6. {% endfor %}
  7. </ul>

上面的代码等效于以下代码,但更短、更简洁,可能也更快:

  1. <ul>
  2. {% if athlete_list %}
  3. {% for athlete in athlete_list %}
  4. <li>{{ athlete.name }}</li>
  5. {% endfor %}
  6. {% else %}
  7. <li>Sorry, no athletes in this list.</li>
  8. {% endif %}
  9. </ul>

if

{% if %} 标签评估一个变量,如果该变量为 “true”(即存在,不为空,并且不是假布尔值),则输出块的内容:

  1. {% if athlete_list %}
  2. Number of athletes: {{ athlete_list|length }}
  3. {% elif athlete_in_locker_room_list %}
  4. Athletes should be out of the locker room soon!
  5. {% else %}
  6. No athletes.
  7. {% endif %}

在上面的例子中, 如果 athlete_list 不是空的, 那么变量 {{ athlete_list|length }} 就会被显示出来.

正如你所看到的,if 标签可能带有一个或多个 {% elif %} 分支,以及一个 {% else %} 分支。当 {% else %} 之前的所有分支条件都不满足时,{% else %} 分支的内容会被显示出来。所有的分支都是可选的。

布尔操作

if 标签可以使用 andornot 来测试多个变量或否定给定变量:

  1. {% if athlete_list and coach_list %}
  2. Both athletes and coaches are available.
  3. {% endif %}
  4. {% if not athlete_list %}
  5. There are no athletes.
  6. {% endif %}
  7. {% if athlete_list or coach_list %}
  8. There are some athletes or some coaches.
  9. {% endif %}
  10. {% if not athlete_list or coach_list %}
  11. There are no athletes or there are some coaches.
  12. {% endif %}
  13. {% if athlete_list and not coach_list %}
  14. There are some athletes and absolutely no coaches.
  15. {% endif %}

在同一个标签中同时使用 andor 子句是允许的,其中 and 的优先级高于 or,例如:

  1. {% if athlete_list and coach_list or cheerleader_list %}

将被解释为:

  1. if (athlete_list and coach_list) or cheerleader_list:
  2. ...

if 标签中使用实际的括号是无效的语法。如果需要小括号来表示优先级,应使用嵌套的 if 标签。

if 标签也可以使用运算符 ==!=<><=>=innot inis`is not,其作用如下:

== 运算符

相等。例如:

  1. {% if somevar == "x" %}
  2. This appears if variable somevar equals the string "x"
  3. {% endif %}
!= 运算符

不相等。例如:

  1. {% if somevar != "x" %}
  2. This appears if variable somevar does not equal the string "x",
  3. or if somevar is not found in the context
  4. {% endif %}
< 运算符

小于。例如:

  1. {% if somevar < 100 %}
  2. This appears if variable somevar is less than 100.
  3. {% endif %}
> 运算符

大于。例如:

  1. {% if somevar > 0 %}
  2. This appears if variable somevar is greater than 0.
  3. {% endif %}
<= 运算符

小于等于。例如:

  1. {% if somevar <= 100 %}
  2. This appears if variable somevar is less than 100 or equal to 100.
  3. {% endif %}
>= 运算符

大于等于。例如:

  1. {% if somevar >= 1 %}
  2. This appears if variable somevar is greater than 1 or equal to 1.
  3. {% endif %}
in 运算符

包含在内。这个运算符由许多 Python 容器支持,用于测试给定的值是否在容器中。以下是一些关于 x in y 如何被解释的示例:

  1. {% if "bc" in "abcdef" %}
  2. This appears since "bc" is a substring of "abcdef"
  3. {% endif %}
  4. {% if "hello" in greetings %}
  5. If greetings is a list or set, one element of which is the string
  6. "hello", this will appear.
  7. {% endif %}
  8. {% if user in users %}
  9. If users is a QuerySet, this will appear if user is an
  10. instance that belongs to the QuerySet.
  11. {% endif %}
not in 操作符

不包含在其中。这是 in 运算符的取反。

is 运算符

对象标识。测试两个值是否是同一个对象。示例:

  1. {% if somevar is True %}
  2. This appears if and only if somevar is True.
  3. {% endif %}
  4. {% if somevar is None %}
  5. This appears if somevar is None, or if somevar is not found in the context.
  6. {% endif %}
is not 运算符

否定的对象标识。测试两个值是否不是同一个对象。这是 is 运算符的否定。示例:

  1. {% if somevar is not True %}
  2. This appears if somevar is not True, or if somevar is not found in the
  3. context.
  4. {% endif %}
  5. {% if somevar is not None %}
  6. This appears if and only if somevar is not None.
  7. {% endif %}

过滤器

你还可以在 if 表达式中使用过滤器。例如:

  1. {% if messages|length >= 100 %}
  2. You have lots of messages today!
  3. {% endif %}

复合表达式

以上所有内容都可以组合成复合表达式。对于这样的表达式,了解表达式计算时运算符的分组方式——也就是优先规则,可能很重要。运算符的优先级,从低到高,如下所示:

  • or
  • and
  • not
  • in
  • ==!=<><=>=

(这与 Python 完全一致)。因此,例如,以下复杂的 if 标签:

  1. {% if a == b or c == d and e %}

…将被解释为:

  1. (a == b) or ((c == d) and e)

如果你需要不同的优先级,你需要使用嵌套的 if 标签。有时,为了不了解优先规则的人,这样做还是比较清楚的。

比较运算符不能像在 Python 或数学表示法中那样“链接”。例如,而不是使用:

  1. {% if a > b > c %} (WRONG)

你应该使用:

  1. {% if a > b and b > c %}

ifchanged

检查一个值是否在循环的最后一次迭代中发生了变化。

{% ifchanged %} 块标签用于循环中。它有两种可能的用法。

  1. 检查自己呈现的内容与之前的状态,并仅在内容发生更改时显示内容。例如,这显示一个日期列表,仅在月份更改时显示月份:

    1. <h1>Archive for {{ year }}</h1>
    2. {% for date in days %}
    3. {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
    4. <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
    5. {% endfor %}
  2. 如果给定一个或多个变量,请检查是否有任何变量发生了变化。例如,以下示例在日期发生变化时显示日期,同时在小时或日期发生变化时显示小时:

    1. {% for date in days %}
    2. {% ifchanged date.date %} {{ date.date }} {% endifchanged %}
    3. {% ifchanged date.hour date.date %}
    4. {{ date.hour }}
    5. {% endifchanged %}
    6. {% endfor %}

ifchanged 标签还可以带有可选的 {% else %} 子句,如果值没有发生变化,则将显示该子句:

  1. {% for match in matches %}
  2. <div style="background-color:
  3. {% ifchanged match.ballot_id %}
  4. {% cycle "red" "blue" %}
  5. {% else %}
  6. gray
  7. {% endifchanged %}
  8. ">{{ match }}</div>
  9. {% endfor %}

include

加载一个模板,并在当前上下文中进行渲染。这是一种在模板中 “包含” 其他模板的方式。

模板名称可以是一个变量,也可以是一个硬编码(引号)字符串,可以是单引号或双引号。

这个示例包含了模板 "foo/bar.html" 的内容:

  1. {% include "foo/bar.html" %}

通常模板名称是相对于模板加载器的根目录而言的。字符串参数也可以是以 ./../ 开头的相对路径,如 extends 标签所述。

这个示例包含了模板名称存储在变量 template_name 中的模板的内容:

  1. {% include template_name %}

变量也可以是任何有 render() 方法并接受上下文的对象。这允许你在你的上下文中引用一个编译的 Template

此外,该变量可以是模板名称的迭代,在这种情况下,将使用第一个可以加载的模板,如 select_template()

一个被包含的模板会在包含它的模板的上下文中呈现。这个例子产生的输出是 "Hello, John!"

  • 上下文:变量 person 设置为 "John",变量 greeting 设置为 "Hello"

  • 模板:

    1. {% include "name_snippet.html" %}
  • name_snippet.html 模板:

    1. {{ greeting }}, {{ person|default:"friend" }}!

你可以使用关键字参数向模板传递额外的上下文:

  1. {% include "name_snippet.html" with person="Jane" greeting="Hello" %}

如果你想仅使用提供的变量(甚至不使用任何变量)来渲染上下文,请使用 only 选项。不会提供其他变量给包含的模板:

  1. {% include "name_snippet.html" with greeting="Hi" only %}

备注

include 标签应被视为 “渲染这个子模板并包含 HTML” 的实现,而不是 “解析这个子模板并包含其内容,就像它是父模板的一部分一样”。这意味着,包含的模板之间没有共享状态——每个包含都是一个完全独立的渲染过程。

块在被包含之前会被执行。这意味着一个包含了另一个模板块的模板将包含 已经被执行和渲染 的块,而不是可以被覆盖的块,例如,一个扩展模板。

load

加载一个自定义模板标签集。

例如,以下模板将加载位于包 package 中的 somelibraryotherlibrary 中注册的所有标签和过滤器:

  1. {% load somelibrary package.otherlibrary %}

你还可以使用 from 参数有选择地从库中加载单个过滤器或标签。在这个例子中,将从 somelibrary 中加载名为 foobar 的模板标签/过滤器:

  1. {% load foo bar from somelibrary %}

更多信息请参见 自定义标签和过滤器库

lorem

显示随机的 “经验之谈” 拉丁文文本。这对于在模板中提供样本数据很有用。

用法:

  1. {% lorem [count] [method] [random] %}

{% lorem %} 标签可以使用零、一、二或三个参数。这些参数是:

参数描述
count一个数字(或变量),包含要生成的段落或字数(默认为 1)。
method字词为 w,HTML 段落为 p,纯文本段落块为 b (默认为 b)。
randomrandom 一词,如果给定,在生成文本时不使用普通段落(“Lorem ipsum dolor sit amet.”)。

举例:

  • {% lorem %} 将输出常见的 “经验之谈” 段落。
  • {% lorem 3 p %} 将输出普通的 “经验之谈” 段落和两个随机段落,每个段落用 HTML <p> 标签包装。
  • {% lorem 2 w random %} 将随机输出两个拉丁语单词。

now

显示当前日期和/或时间,根据给定的字符串使用格式。这些字符串可以包含格式指定符,如 date 过滤器部分所述。

例如:

  1. It is {% now "jS F Y H:i" %}

请注意,如果要使用“原始”值,可以对格式字符串进行反斜杠转义。在这个示例中,”o” 和 “f” 都进行了反斜杠转义,因为否则它们分别是显示年份和时间的格式字符串:

  1. It is the {% now "jS \o\f F" %}

这样就会显示为 “It is the 4th of September”。

备注

传递的格式也可以是预定义的格式之一:DATE_FORMATDATETIME_FORMATSHORT_DATE_FORMATSHORT_DATETIME_FORMAT。预定义的格式可能会根据当前的区域设置以及是否启用 本地格式化 而有所不同,例如:

  1. It is {% now "SHORT_DATETIME_FORMAT" %}

你还可以使用语法 {% now "Y" as current_year %} 将输出(作为字符串)存储在变量中。这在你想在模板标签内使用 {% now %},如 blocktranslate 这样的标签时非常有用:

  1. {% now "Y" as current_year %}
  2. {% blocktranslate %}Copyright {{ current_year }}{% endblocktranslate %}

querystring

New in Django 5.1.

Outputs a URL-encoded formatted query string based on the provided parameters.

This tag requires a QueryDict instance, which defaults to request.GET if none is provided.

If the QueryDict is empty and no additional parameters are provided, an empty string is returned. A non-empty result includes a leading "?".

Using request.GET as default

To use request.GET as the default QueryDict instance, the django.template.context_processors.request context processor should be enabled. If it’s not enabled, you must either explicitly pass the request object into the template context, or provide a QueryDict instance to this tag.

Basic usage

  1. {% querystring %}

Outputs the current query string verbatim. So if the query string is ?color=green, the output would be ?color=green.

  1. {% querystring size="M" %}

Outputs the current query string with the addition of the size parameter. Following the previous example, the output would be ?color=green&size=M.

Custom QueryDict

  1. {% querystring my_query_dict %}

You can provide a custom QueryDict to be used instead of request.GET. So if my_query_dict is <QueryDict: {'color': ['blue']}>, this outputs ?color=blue.

Setting items

  1. {% querystring color="red" size="S" %}

Adds or modifies parameters in the query string. Each keyword argument will be added to the query string, replacing any existing value for that key. For instance, if the current query string is ?color=green, the output will be ?color=red&size=S.

Removing items

  1. {% querystring color=None %}

Passing None as the value removes the parameter from the query string. For example, if the current query string is ?color=green&size=M, the output will be ?size=M.

Handling lists

  1. {% querystring color=my_list %}

If my_list is ["red", "blue"], the output will be ?color=red&color=blue, preserving the list structure in the query string.

Dynamic usage

A common example of using this tag is to preserve the current query string when displaying a page of results, while adding a link to the next and previous pages of results. For example, if the paginator is currently on page 3, and the current query string is ?color=blue&size=M&page=3, the following code would output ?color=blue&size=M&page=4:

  1. {% querystring page=page.next_page_number %}

You can also store the value in a variable. For example, if you need multiple links to the same page, define it as:

  1. {% querystring page=page.next_page_number as next_page %}

regroup

通过一个共同的属性将一个相似的对象列表重新分组。

这个复杂的标签通过一个例子得到了最好的说明:假设 cities 是一个由包含 "name""population""country" 键的字典所代表的城市列表。

  1. cities = [
  2. {"name": "Mumbai", "population": "19,000,000", "country": "India"},
  3. {"name": "Calcutta", "population": "15,000,000", "country": "India"},
  4. {"name": "New York", "population": "20,000,000", "country": "USA"},
  5. {"name": "Chicago", "population": "7,000,000", "country": "USA"},
  6. {"name": "Tokyo", "population": "33,000,000", "country": "Japan"},
  7. ]

…而你想显示一个按国家排序的分层列表,像这样:

  • India
    • Mumbai: 19,000,000
    • Calcutta: 15,000,000
  • USA
    • New York: 20,000,000
    • Chicago: 7,000,000
  • Japan
    • Tokyo: 33,000,000

你可以使用 {% regroup %} 标签将城市列表按国家分组。以下模板代码片段将实现这一目标:

  1. {% regroup cities by country as country_list %}
  2. <ul>
  3. {% for country in country_list %}
  4. <li>{{ country.grouper }}
  5. <ul>
  6. {% for city in country.list %}
  7. <li>{{ city.name }}: {{ city.population }}</li>
  8. {% endfor %}
  9. </ul>
  10. </li>
  11. {% endfor %}
  12. </ul>

让我们来看看这个例子。{% regroup %} 需要三个参数:要重新分组的列表、要分组的属性和结果列表的名称。在这里,我们通过 country 属性对 cities 列表进行重新分组,并将结果称为 country_list

{% regroup %} 产生一个 组对象 的列表(在本例中为 country_list)。组对象是 namedtuple() 的实例,有两个字段。

  • grouper —— 被分组的项目(例如,“India” 或 “Japan” 等字符串)。
  • list —— 本组所有项目的清单(例如,country=’India’ 的所有城市的清单)。

因为 {% regroup %} 生成 namedtuple() 对象,你也可以将前面的示例写成:

  1. {% regroup cities by country as country_list %}
  2. <ul>
  3. {% for country, local_cities in country_list %}
  4. <li>{{ country }}
  5. <ul>
  6. {% for city in local_cities %}
  7. <li>{{ city.name }}: {{ city.population }}</li>
  8. {% endfor %}
  9. </ul>
  10. </li>
  11. {% endfor %}
  12. </ul>

请注意,{% regroup %} 并没有对其输入进行排序!我们的例子依赖于这样一个事实: cities 列表首先是按 country 排序的。如果 cities 列表没有按 country 排序,重新分组就会天真地显示一个国家的多个组。例如,如果 cities 列表设置成这样(注意,国家没有被归为一组)。

  1. cities = [
  2. {"name": "Mumbai", "population": "19,000,000", "country": "India"},
  3. {"name": "New York", "population": "20,000,000", "country": "USA"},
  4. {"name": "Calcutta", "population": "15,000,000", "country": "India"},
  5. {"name": "Chicago", "population": "7,000,000", "country": "USA"},
  6. {"name": "Tokyo", "population": "33,000,000", "country": "Japan"},
  7. ]

有了这个 cities 的输入,上面的 {% regroup %} 模板代码就会有如下输出。

  • India
    • Mumbai: 19,000,000
  • USA
    • New York: 20,000,000
  • India
    • Calcutta: 15,000,000
  • USA
    • Chicago: 7,000,000
  • Japan
    • Tokyo: 33,000,000

解决这个问题最简单的方法是在你的视图代码中确保数据是按照你想显示的方式来排序的。

另一种解决方案是使用 dictsort 过滤器在模板中对数据进行排序,如果你的数据是一个字典列表的话:

  1. {% regroup cities|dictsort:"country" by country as country_list %}

对其他属性进行分组

对于 regroup 标签,任何有效的模板查找都是合法的分组属性,包括方法、属性、字典键和列表项。例如,如果 “country” 字段是一个外键,指向一个带有属性 “description” 的类,你可以这样使用:

  1. {% regroup cities by country.description as country_list %}

或者,如果 country 是一个带有 choices 的字段,它将作为属性具有 get_FOO_display() 方法,允许你按显示字符串而不是 choices 键进行分组:

  1. {% regroup cities by get_country_display as country_list %}

{{ country.grouper }} 现在将显示 choices 集的值域,而不是键。

resetcycle

重置之前的 cycle ,使其在下一次遇到时从第一项开始重新启动。如果没有参数,{% resetcycle %} 将重置模板中定义的最后一个 {% cycle %}

使用实例:

  1. {% for coach in coach_list %}
  2. <h1>{{ coach.name }}</h1>
  3. {% for athlete in coach.athlete_set.all %}
  4. <p class="{% cycle 'odd' 'even' %}">{{ athlete.name }}</p>
  5. {% endfor %}
  6. {% resetcycle %}
  7. {% endfor %}

这个示例将返回以下 HTML:

  1. <h1>Gareth</h1>
  2. <p class="odd">Harry</p>
  3. <p class="even">John</p>
  4. <p class="odd">Nick</p>
  5. <h1>John</h1>
  6. <p class="odd">Andrea</p>
  7. <p class="even">Melissa</p>

请注意第一个代码块以 class="odd" 结束,而新的代码块以 class="odd" 开始。如果没有 {% resetcycle %} 标签,第二块将以 class="even" 开始。

你还可以重置具有名称的循环标记:

  1. {% for item in list %}
  2. <p class="{% cycle 'odd' 'even' as stripe %} {% cycle 'major' 'minor' 'minor' 'minor' 'minor' as tick %}">
  3. {{ item.data }}
  4. </p>
  5. {% ifchanged item.category %}
  6. <h1>{{ item.category }}</h1>
  7. {% if not forloop.first %}{% resetcycle tick %}{% endif %}
  8. {% endifchanged %}
  9. {% endfor %}

在这个例子中,我们既有奇数/偶数行的交替,也有每第五行的 “主要” 行。只有当类别发生变化时,才会重置五行循环。

spaceless

删除 HTML 标签之间的空白。这包括制表符和换行符。

使用实例:

  1. {% spaceless %}
  2. <p>
  3. <a href="foo/">Foo</a>
  4. </p>
  5. {% endspaceless %}

这个示例将返回以下 HTML:

  1. <p><a href="foo/">Foo</a></p>

只有 标记 之间的空格被删除,而不是标记和文本之间的空格。在这个示例中,Hello 周围的空格不会被删除:

  1. {% spaceless %}
  2. <strong>
  3. Hello
  4. </strong>
  5. {% endspaceless %}

templatetag

输出用于组成模板标签的语法字符之一。

模板系统没有“转义”单个字符的概念。但是,你可以使用 {% templatetag %} 标签来显示其中一个模板标记字符组合。

这个参数告诉我们要输出哪个模板位:

参数输出
openblock{%
closeblock%}
openvariable{{
closevariable}}
openbrace{
closebrace}
opencomment{#
closecomment#}

示例用法:

  1. The {% templatetag openblock %} characters open a block.

另请参阅 verbatim 标签以了解包含这些字符的另一种方式。

url

返回与给定视图和可选参数相匹配的绝对路径引用(不含域名的 URL)。路径中的任何特殊字符将使用 iri_to_uri() 进行编码。

这是一种在模板中输出链接的方法,而不违反 DRY 原则,因为不需要在模板中硬编码 URL:

  1. {% url 'some-url-name' v1 v2 %}

第一个参数是一个 URL 模式名称。它可以是带引号的文字或任何其他上下文变量。额外的参数是可选的,并且应该是用作 URL 参数的空格分隔值。上面的示例展示了传递位置参数。或者,你也可以使用关键字语法:

  1. {% url 'some-url-name' arg1=v1 arg2=v2 %}

不要在一次调用中同时混合使用位置和关键字语法。URLconf 所要求的所有参数都应该存在。

例如,假设你有一个视图,app_views.client,它的 URLconf 需要一个客户端 ID(这里,client() 是视图文件 app_views.py 中的一个方法)。URLconf 行可能是这样的:

  1. path("client/<int:id>/", app_views.client, name="app-views-client")

如果这个应用的 URLconf 被包含在项目的 URLconf 中,路径如下:

  1. path("clients/", include("project_name.app_name.urls"))

…然后,在模板中,你可以像这样创建到这个视图的链接:

  1. {% url 'app-views-client' client.id %}

模板标签将输出字符串 /clients/client/123/

请注意,如果你要反查的 URL 不存在,你会得到一个 NoReverseMatch 的异常引发,这将导致你的网站显示一个错误页面。

如果你想获取一个 URL 而不显示它,可以使用稍微不同的调用方式:

  1. {% url 'some-url-name' arg arg2 as the_url %}
  2. <a href="{{ the_url }}">I'm linking to {{ the_url }}</a>

as var 语法创建的变量范围是 {% block %},其中出现 {% url %} 标签。

这种 {% url ... as var %} 语法如果视图不存在将 不会 引发错误。在实际应用中,你可以使用这种方式链接到可选的视图:

  1. {% url 'some-url-name' as the_url %}
  2. {% if the_url %}
  3. <a href="{{ the_url }}">Link to optional stuff</a>
  4. {% endif %}

如果你想获取带命名空间的 URL,请指定完全限定的名称:

  1. {% url 'myapp:view-name' %}

这将遵循正常的 命名空间 URL 解析策略,包括使用上下文提供的关于当前应用程序的任何提示。

警告

不要忘记在 URL 模式的 name 周围加上引号,否则其值将被解释为一个上下文变量!

verbatim

停止模板引擎渲染此块标签的内容。

常见的用法是允许一个与 Django 语法冲突的 JavaScript 模板层。例如:

  1. {% verbatim %}
  2. {{if dying}}Still alive.{{/if}}
  3. {% endverbatim %}

你还可以指定一个特定的闭合标签,允许在未渲染的内容中使用 {% endverbatim %}

  1. {% verbatim myblock %}
  2. Avoid template rendering via the {% verbatim %}{% endverbatim %} block.
  3. {% endverbatim myblock %}

widthratio

对于创建条形图等,该标签计算给定值与最大值的比率,然后将该比率应用于一个常数。

例如:

  1. <img src="bar.png" alt="Bar"
  2. height="10" width="{% widthratio this_value max_value max_width %}">

如果 this_value 是175,max_value 是 200,max_width 是 100,则上例中的图像宽度为 88 像素(因为 175 / 200 = 0.875;0.875 * 100 = 87.5,四舍五入为 88)。

在某些情况下,你可能希望将 widthratio 的结果捕获到一个变量中。这在像下面这样的 blocktranslate 中可能很有用:

  1. {% widthratio this_value max_value max_width as width %}
  2. {% blocktranslate %}The width is: {{ width }}{% endblocktranslate %}

with

将一个复杂的变量缓存在一个简单的名称下。当多次访问一个 “昂贵的” 方法(例如,访问数据库的方法)时,这很有用。

例如:

  1. {% with total=business.employees.count %}
  2. {{ total }} employee{{ total|pluralize }}
  3. {% endwith %}

被填充的变量(在上面的例子中,total)只有在 {% with %}{% endwith %} 标签之间才能使用。

你可以分配多个上下文变量:

  1. {% with alpha=1 beta=2 %}
  2. ...
  3. {% endwith %}

备注

仍然支持以前比较啰嗦的格式: {% with business.employees.count as total %}

内置过滤器参考

add

将参数添加到值中。

例如:

  1. {{ value|add:"2" }}

如果 value4,那么输出将是 6

这个过滤器将首先尝试将两个值强制转为整数。如果失败了,它将尝试将两个值加在一起。这对某些数据类型(字符串、列表等)有效,而对其他类型则失败。如果失败,结果将是一个空字符串。

例如,如果我们有:

  1. {{ first|add:second }}

同时 first[1, 2, 3] 并且 second[4, 5, 6],则输出为 [1, 2, 3, 4, 5, 6]

警告

可以强制转为整数的字符串将被 相加,而不是像上面上一个例子那样被连在一起。

addslashes

在引号前添加斜杠。对 CSV 中的字符串进行转义很有用,例如。

例如:

  1. {{ value|addslashes }}

如果 value"I'm using Django",那么输出将是 "I\'m using Django"

capfirst

将值的第一个字符大写。如果第一个字符不是字母,这个过滤器就没有效果。

例如:

  1. {{ value|capfirst }}

如果 value"django",则输出为 "Django"

center

在给定宽度的字段中使数值居中。

例如:

  1. "{{ value|center:"15" }}"

如果 value"Django",输出将是 " Django "

cut

从给定的字符串中删除参数的所有值。

例如:

  1. {{ value|cut:" " }}

如果 value"String with spaces",输出将是 "Stringwithspaces"

date

根据给定的格式设置日期。

使用与 PHP 的 date() 函数类似的格式,但有一些差异。

备注

这些格式字符在模板之外的 Django 中没有使用。它们被设计成与 PHP 兼容,以方便设计师过渡。

可用的格式字符串:

格式字符描述输出示例
  
d某月的某日,2 位带前导零的数字。‘01’‘31’
j某月的某日,前面没有零。‘1’‘31’
D某周的某日,3 个字母的文本。‘Fri’
l某周的某日,长文本。‘Friday’
S某月英文序号后缀的某日,2 个字符。‘st’‘nd’‘rd’‘th’
w某周的某日,不含前导零的数字。‘0’ (星期天)到 ‘6’ (星期六)
z某年的某日1366
  
W年的 ISO-8601 周数,周从星期一开始。153
  
m月份,2 位数,前面加 0。‘01’‘12’
n没有前导零的月份。‘1’‘12’
M月,3 个字母的文本。‘Jan’
b月,小写的 3 个字母的文本。‘jan’
E月,特定地域的替代表示方法,通常用于长日期表示。‘listopada’ (波兰语,与 ‘Listopad’ 相对)
F月,长文本。‘January’
N美联社风格的月份缩写。专属扩展。‘Jan.’‘Feb.’‘March’‘May’
t特定月份的天数。2831
  
y年,2 位带前导零的数字。‘00’‘99’
Y年,4 位带前导零的数字。‘0001’, …, ‘1999’, …, ‘9999’
L是否为闰年的布尔值。TrueFalse
oISO-8601 周数年,对应于使用闰周的 ISO-8601 周数(W)。更常见的年份格式见 Y。‘1999’
时间  
g小时,12 小时格式,无前导零。‘1’‘12’
G小时,24 小时格式,无前导零。‘0’‘23’
h小时,12 小时格式。‘01’‘12’
H小时,24 小时格式。‘00’‘23’
i分钟。‘00’‘59’
s秒,2 位带前导零的数字。‘00’‘59’
u微秒。000000999999
a‘a.m.’‘p.m.’ (请注意,这与 PHP 的输出略有不同,因为这包括了与美联社风格一致的句号)。‘a.m.’
A‘AM’‘PM’‘AM’
f时间,以 12 小时格式的小时和分钟为单位,如果是零,就把分钟去掉。专属扩展。‘1’‘1:30’
P时间,以 12 小时格式的小时、分钟和 ‘a.m.’/’p.m.’ 为单位,如果分钟为零,则不写,如果有,则写上特殊大小写的字符串 ‘midnight’ 和 ‘noon’。专属扩展。‘1 a.m.’‘1:30 p.m.’‘midnight’‘noon’‘12:30 p.m.’
时区  
e时区名称。可以是任何格式,也可以返回一个空字符串,取决于日期时间。‘’‘GMT’‘-500’‘US/Eastern’ 等。
I夏令时,无论是否生效。‘1’‘0’
O与格林威治时间的时差。‘+0200’
T本机的时区。‘EST’‘MDT’
Z时区偏移以秒为单位。UTC 以西的时区偏移总是负数,UTC 以东的时区偏移总是正数。-4320043200
日期/时间  
cISO 8601 格式。 (注意:与“Z”、“O”或“r”等其他格式化程序不同,如果值是原始日期时间,“c”格式化程序将不会添加时区偏移量(参见 datetime.tzinfo)。2008-01-02T10:30:00.000123+02:002008-01-02T10:30:00.000123 如果日期时间是本地的
rRFC 5322 格式的日期。‘Thu, 21 Dec 2000 16:01:07 +0200’
U自 Unix 纪元(1970 年 1 月 1 日 00:00:00 UTC)以来的秒数。 

例如:

  1. {{ value|date:"D d M Y" }}

如果 value 是一个 datetime 对象(例如,datetime.datetime.datetime.now() 的结果),输出将是字符串 'Wed 09 Jan 2008'

传递的格式可以是预定义的 DATE_FORMATDATETIME_FORMATSHORT_DATE_FORMATSHORT_DATETIME_FORMAT, 或者是使用上表中显示的格式指定器的自定义格式。请注意,预定义的格式可能会根据当前的 locale 而有所不同。

假设 LANGUAGE_CODE 是,例如,"es",那么对于:

  1. {{ value|date:"SHORT_DATE_FORMAT" }}

输出将是字符串 "09/01/2008" (Django 自带的 "SHORT_DATE_FORMAT" 格式指定符是 "d/m/Y")。

当没有使用格式字符串时,将使用 DATE_FORMAT 格式说明符。假设与前面的示例相同的设置:

  1. {{ value|date }}

输出 9 de Enero de 2008DATE_FORMAT' 格式指定符为 r'j\d\e F\d\e Y')。“d” 和 “e” 都是反斜杠,因为否则每一个都是一个格式字符串,分别显示日期和时区名称。

你可以将 datetime 过滤器组合使用来渲染一个 datetime 值的完整表示。例如:

  1. {{ value|date:"D d M Y" }} {{ value|time:"H:i" }}

default

如果值为 False,则使用给定的默认值。否则,使用该值。

例如:

  1. {{ value|default:"nothing" }}

如果 value"" (空字符串),输出将是 nothing

default_if_none

如果(也只有当)值是 None,使用给定的默认值。否则,使用该值。

请注意,如果给定一个空字符串,将 不会 使用默认值。如果你想使用空字符串,请使用 default 过滤器。

例如:

  1. {{ value|default_if_none:"nothing" }}

如果 valueNone,则输出为 nothing

dictsort

获取一个字典列表,并按照参数中给出的键排序返回该列表。

例如:

  1. {{ value|dictsort:"name" }}

如果 value 是:

  1. [
  2. {"name": "zed", "age": 19},
  3. {"name": "amy", "age": 22},
  4. {"name": "joe", "age": 31},
  5. ]

那么输出将是:

  1. [
  2. {"name": "amy", "age": 22},
  3. {"name": "joe", "age": 31},
  4. {"name": "zed", "age": 19},
  5. ]

你还可以做更复杂的事情,比如:

  1. {% for book in books|dictsort:"author.age" %}
  2. * {{ book.title }} ({{ book.author.name }})
  3. {% endfor %}

如果 books 是:

  1. [
  2. {"title": "1984", "author": {"name": "George", "age": 45}},
  3. {"title": "Timequake", "author": {"name": "Kurt", "age": 75}},
  4. {"title": "Alice", "author": {"name": "Lewis", "age": 33}},
  5. ]

那么输出将是:

  1. * Alice (Lewis)
  2. * 1984 (George)
  3. * Timequake (Kurt)

dictsort 也可以按指定索引处的元素对列表的列表(或任何其他实现了 __getitem__() 的对象)进行排序。例如:

  1. {{ value|dictsort:0 }}

如果 value 是:

  1. [
  2. ("a", "42"),
  3. ("c", "string"),
  4. ("b", "foo"),
  5. ]

那么输出将是:

  1. [
  2. ("a", "42"),
  3. ("b", "foo"),
  4. ("c", "string"),
  5. ]

你必须将索引作为整数而不是字符串传递。以下示例会产生空输出:

  1. {{ values|dictsort:"0" }}

按指定索引处的元素排序不支持在字典上进行。

dictsortreversed

取一个字典列表,并按参数中给出的键反向排序返回该列表。这与上面的过滤器的工作原理完全相同,但返回的值将是倒序的。

divisibleby

如果数值被参数整除,则返回 True

例如:

  1. {{ value|divisibleby:"3" }}

如果 value21,则输出为 True

escape

转义字符串的 HTML。具体来说,它可以进行这些替换。

  • < 被替换为 &lt;
  • > 被替换为 &gt;
  • ' (单引号)被替换为 &#x27;
  • " (双引号)被替换为 &quot;
  • & 被替换为 &amp;

escape 应用到一个通常会对结果进行自动转义的变量上,结果只会进行一轮转义。所以即使在自动转义环境中使用这个函数也是安全的。如果你想进行多次转义,请使用 force_escape 过滤器。

例如,当 autoescape 关闭时,你可以对字段应用 escape

  1. {% autoescape off %}
  2. {{ title|escape }}
  3. {% endautoescape %}

escape 与其他过滤器链接起来:

如在 autoescape 部分提到的,当包括 escape 在内的过滤器链接在一起时,如果前面的过滤器将一个潜在不安全的字符串标记为安全,由于 autoescapeoff 而导致没有转义,可能会导致意外的结果。

在这种情况下,链接 escape 不会重新转义已被标记为安全的字符串。

这在使用操作序列的过滤器时尤为重要,例如 join。如果需要转义序列中的每个元素,请使用专用的 escapeseq 过滤器。

escapejs

将字符转义以用作整个 JavaScript 字符串文字,可以用单引号或双引号,如下所示。此过滤器不会使字符串适用于 “JavaScript 模板文字” (JavaScript 反引号语法)。不支持上面未列出的任何其他用途。通常建议将数据传递使用 HTML data- 属性或 json_script 过滤器,而不是在嵌入的 JavaScript 中使用。

例如:

  1. <script>
  2. let myValue = '{{ value|escapejs }}'

escapeseq

New in Django 5.0.

escape 过滤器应用于序列的每个元素。与其他操作序列的过滤器(如 join)结合使用时非常有用。例如:

  1. {% autoescape off %}
  2. {{ my_list|escapeseq|join:", " }}
  3. {% endautoescape %}

filesizeformat

以 “人类可读” 的文件大小为格式(如 '13 KB''4.1 MB''102 bytes' 等)。

例如:

  1. {{ value|filesizeformat }}

如果 value 是 123456789,则输出为 117.7 MB

文件大小和 SI 单位

严格来说,filesizeformat 并不符合国际单位制,国际单位制建议在字节大小以 1024 的幂计算时使用 KiB、MiB、GiB 等单位(这里就是这种情况)。相反,Django 使用了传统的单位名称(KB、MB、GB 等),对应的是比较常用的名称。

first

返回列表中的第一个项目。

例如:

  1. {{ value|first }}

如果 value 是列表 ['a', 'b', 'c'],则输出为 'a'

floatformat

当不使用参数时,将浮点数四舍五入到小数点后一位——但只在有小数部分要显示的情况下。例如:

value模板输出
34.23234{{ value|floatformat }}34.2
34.00000{{ value|floatformat }}34
34.26000{{ value|floatformat }}34.3

如果与数字整数参数一起使用,floatform 将一个数字四舍五入到小数点后几位。例如:

value模板输出
34.23234{{ value|floatformat:3 }}34.232
34.00000{{ value|floatformat:3 }}34.000
34.26000{{ value|floatformat:3 }}34.260

特别有用的是传递 0(零)作为参数,它将把浮点数舍入到最接近的整数。

value模板输出
34.23234{{ value|floatformat:”0” }}34
34.00000{{ value|floatformat:”0” }}34
39.56000{{ value|floatformat:”0” }}40

如果传递给 floatform 的参数是负数,它将把一个数字四舍五入到小数点后的位数——但只在有小数部分要显示的情况下。例如:

value模板输出
34.23234{{ value|floatformat:”-3” }}34.232
34.00000{{ value|floatformat:”-3” }}34
34.26000{{ value|floatformat:”-3” }}34.260

如果传递给 floatformat 的参数具有 g 后缀,它将强制使用当前区域设置的 THOUSAND_SEPARATOR 进行分组。例如,当活动区域设置为 en (英语)时:

value模板输出
34232.34{{ value|floatformat:”2g” }}34,232.34
34232.06{{ value|floatformat:”g” }}34,232.1
34232.00{{ value|floatformat:”-3g” }}34,232

输出始终是本地化的(与 {% localize off %} 标签无关),除非传递给 floatformat 的参数具有 u 后缀,这将强制禁用本地化。例如,当活动区域设置为 pl (波兰语)时:

value模板输出
34.23234{{ value|floatformat:”3” }}34,232
34.23234{{ value|floatformat:”3u” }}34.232

在没有参数的情况下使用 floatformat 相当于在参数为 -1 的情况下使用 floatformat

force_escape

对字符串进行 HTML 转义处理(详情请参见 escape 过滤器)。这个过滤器会 立即 应用,并返回一个新的转义字符串。在极少数情况下,当你需要多次转义或想对转义结果应用其他过滤器时,这很有用。通常情况下,你要使用 escape 过滤器。

例如,如果你想捕获由 linebreaks 过滤器创建的 <p> HTML 元素:

  1. {% autoescape off %}
  2. {{ body|linebreaks|force_escape }}
  3. {% endautoescape %}

get_digit

给定一个整数,返回要求的数字,其中 1 是最右边的数字,2 是最右边的数字,等等。对于无效的输入(如果输入或参数不是整数,或者参数小于 1),返回原始值。否则,输出总是一个整数。

例如:

  1. {{ value|get_digit:"2" }}

如果 value123456789,则输出为 8

iriencode

将 IRI(国际化资源标识符)转换为适合包含在 URL 中的字符串。如果你想在 URL 中使用包含非 ASCII 字符的字符串,这一点是必要的。

在已经通过 urlencode 过滤器的字符串上使用这个过滤器是安全的。

例如:

  1. {{ value|iriencode }}

如果 value"?test=I ♥ Django",则输出将是 "?test=I%20%E2%99%A5%20Django"

join

用字符串连接一个列表,就像 Python 的 str.join(list) 一样。

例如:

  1. {{ value|join:" // " }}

如果 value 是列表 ['a', 'b', 'c'],输出将是字符串 "a // b // c"

json_script

安全地将 Python 对象输出为 JSON,用 <script> 标签包装,准备好与 JavaScript 一起使用。

参数: 可选的 <script> 标签的 HTML “id”。

例如:

  1. {{ value|json_script:"hello-data" }}

如果 value 是字典 {'hello':'world'},则输出为:

  1. <script id="hello-data" type="application/json">{"hello": "world"}</script>

由此产生的数据可以用 JavaScript 来访问,比如这样:

  1. const value = JSON.parse(document.getElementById('hello-data').textContent);

XSS 攻击可以通过转义字符 “<”、“>” 和 “&” 来缓解。例如,如果 value{'hello': 'world</script>&amp;'},则输出为:

  1. <script id="hello-data" type="application/json">{"hello": "world\\u003C/script\\u003E\\u0026amp;"}</script>

这与严格的内容安全策略兼容,禁止在页面中执行脚本。它还保持了被动数据和可执行代码之间的明确分离。

last

返回列表中的最后一项。

例如:

  1. {{ value|last }}

如果 value 是列表 ['a', 'b', 'c', 'd'],输出将是字符串 "d"

length

返回值的长度。这对字符串和列表都有效。

例如:

  1. {{ value|length }}

如果 value['a', 'b', 'c', 'd']"abcd",输出将是 4

过滤器对未定义的变量返回 0

linebreaks

用适当的 HTML 替换纯文本中的换行符;一个新行成为 HTML 换行符(<br>),一个新行后的空行成为段落换行符(</p>)。

例如:

  1. {{ value|linebreaks }}

如果 valueJoel\nis a slug,则输出为 <p>Joel<br>is a slug</p>

linebreaksbr

将一段纯文本中的所有换行符转换为 HTML 换行符(<br>)。

例如:

  1. {{ value|linebreaksbr }}

如果 valueJoel/nis a slug,则输出为 Joel<br>is a slug

linenumbers

显示带有行号的文本。

例如:

  1. {{ value|linenumbers }}

如果 value 是:

  1. one
  2. two
  3. three

输出将是:

  1. 1. one
  2. 2. two
  3. 3. three

ljust

左对齐给定宽度的字段中的值。

参数: 字段大小

例如:

  1. "{{ value|ljust:"10" }}"

如果 valueDjango,则输出为 "Django "

lower

将一个字符串转换为全小写。

例如:

  1. {{ value|lower }}

如果 valueTotally LOVING this Album!,则输出为 totally loving this album!

make_list

返回变成列表的值。对于字符串,它是一个字符列表。对于整数来说,在创建列表之前,参数会被转换为一个字符串。

例如:

  1. {{ value|make_list }}

如果 value 是字符串 "Joel",输出将是列表 ['J', 'o', 'e', 'l']。如果 value123,输出将是列表 ['1','2','3']

phone2numeric

将一个电话号码(可能包含字母)转换为其数字等价物。

输入的不一定是有效的电话号码。这将很乐意转换任何字符串。

例如:

  1. {{ value|phone2numeric }}

如果 value800-COLLECT,则输出为 800-2655328

pluralize

如果值不是 1'1' 或长度为 1 的对象,则返回复数后缀。 默认情况下,后缀为 's'

例如:

  1. You have {{ num_messages }} message{{ num_messages|pluralize }}.

如果 num_messages1,输出将是 You have 1 message. 如果 num_messages2,输出将是 You have 2 messages.

对于需要后缀而不是 's' 的词,你可以提供一个备用后缀作为过滤器的参数。

例如:

  1. You have {{ num_walruses }} walrus{{ num_walruses|pluralize:"es" }}.

对于不使用简单后缀进行复数的单词,你可以同时指定单数和复数后缀,并用逗号分隔。

例如:

  1. You have {{ num_cherries }} cherr{{ num_cherries|pluralize:"y,ies" }}.

备注

使用 blocktranslate 来实现翻译字符串的复数化。

pprint

pprint.pprint() 的一个包装器 —— 真的是用来调试的。

random

从给定列表中随机返回一个项目。

例如:

  1. {{ value|random }}

如果 value 是列表 ['a', 'b', 'c', 'd'],输出可能是 "b"

rjust

右对齐给定宽度的字段中的值。

参数: 字段大小

例如:

  1. "{{ value|rjust:"10" }}"

如果 valueDjango,输出将是 " Django"

safe

标记一个字符串在输出前不需要进一步的 HTML 转义。当自动转义关闭时,该过滤器没有效果。

备注

如果你正在链式使用过滤器,在 safe 之后应用的过滤器可能会使内容再次变得不安全。例如,以下代码会原样打印变量,不进行转义:

  1. {{ var|safe|escape }}

safeseq

对序列的每个元素应用 safe 过滤器。与其他操作序列的过滤器(如 join)结合使用时非常有用。例如:

  1. {{ some_list|safeseq|join:", " }}

在这种情况下,你不能直接使用 safe 过滤器,因为它会首先将变量转换为字符串,而不是处理序列中的单个元素。

slice

返回列表的一个片段。

使用与 Python 的列表切片相同的语法。有关介绍,请参阅 Python 文档

例如:

  1. {{ some_list|slice:":2" }}

如果 some_list['a', 'b', 'c'],输出将是 ['a', 'b']

slugify

转换为 ASCII 码。将空格转换为连字符。移除非字母数字、下划线或连字符的字符。转换为小写字母。还可以去除前导和尾部的空白。

例如:

  1. {{ value|slugify }}

如果 value"Joel is a slug",那么输出将是 "joel-is-a-slug"

stringformat

根据参数——字符串格式化指定器,对变量进行格式化。这个指定符使用 printf-style String Formatting 语法,例外的是前面的 “%” 被删除。

例如:

  1. {{ value|stringformat:"E" }}

如果 value10,则输出为 1.000000E+01

striptags

尽一切努力剥离所有 [X]HTML 标签。

例如:

  1. {{ value|striptags }}

如果 value"<b>Joel</b> <button>is</button> a <span>slug</span>", 那么输出就会是 "Joel is a slug".

没有安全保证

请注意,striptags 不会保证其输出是 HTML 安全的,特别是在输入为非有效 HTML 的情况下。因此,绝不要safe 过滤器应用于 striptags 输出。如果你正在寻找更健壮的解决方案,请考虑使用第三方的 HTML 清理工具。

time

根据给定的格式对时间进行格式化。

给定的格式可以是预定义的 TIME_FORMAT,也可以是自定义的格式,和 date 过滤器一样。请注意,预定义的格式是依赖于 locale 的。

例如:

  1. {{ value|time:"H:i" }}

如果 value 相当于 datetime.datetime.now(),输出将是字符串 "01:23"

请注意,如果要使用“原始”值,可以对格式字符串进行反斜杠转义。在这个示例中,”h” 和 “m” 都进行了反斜杠转义,因为否则它们分别是显示小时和月份的格式字符串:

  1. {{ value|time:"H\h i\m" }}

这样就会显示为 “01h 23m”。

另一个例子:

假设 LANGUAGE_CODE 是,例如,"de",那么对于:

  1. {{ value|time:"TIME_FORMAT" }}

输出将是字符串 "01:23" (Django 自带的 "TIME_FORMAT" 格式指定符为 "H:i")。

time 过滤器只接受格式字符串中与一天中的时间有关的参数,而不是日期。如果你需要格式化一个 date 值,请使用 date 过滤器来代替(如果你需要渲染一个完整的 datetime 值,则使用 time)。

上述规则有一个例外。当传递一个附带时区信息的 datetime 值时(一个 时区感知datetime 实例),time 过滤器将接受与时区相关的 格式指定符 'e''O''T''Z'

当没有使用格式字符串时,将使用 TIME_FORMAT 格式说明符:

  1. {{ value|time }}

与以下代码相同:

  1. {{ value|time:"TIME_FORMAT" }}

timesince

将日期格式化为自该日期起的时间(如 “4 days, 6 hours”)。

接受一个可选参数,该参数是一个包含要用作比较点的日期的变量(如果没有参数,比较点就是 现在)。例如,如果 blog_date 是一个表示2006年6月1日午夜的日期实例,而 comment_date 是一个表示 2006 年 6 月 1 日上午 8:00 的日期实例,那么以下代码将返回 “8 小时”:

  1. {{ blog_date|timesince:comment_date }}

比较本地偏移和感知偏移的日期会返回一个空字符串。

分钟是使用的最小单位,凡是相对于比较点来说是未来的日期,都会返回 “0 minutes”。

timeuntil

timesince 类似,不同的是,它测量的是从现在到给定日期或日期时间的时间。例如,如果今天是 2006 年 6 月 1 日,而 conference_date 是一个持有 2006 年 6 月 29 日的日期实例,那么 {conference_date|timeuntil }} 将返回 “4 weeks”。

接受一个可选参数,该参数是一个包含要用作比较点的日期的变量(而不是 现在)。如果 from_date 包含了 2006 年 6 月 22 日,那么以下代码将返回 “1 周”:

  1. {{ conference_date|timeuntil:from_date }}

比较本地偏移和感知偏移的日期会返回一个空字符串。

分钟是使用的最小单位,相对于比较点而言,任何处于过去的日期都将返回 “0 minutes”。

title

通过使单词以大写字母开头,其余字符以小写字母开头,将字符串转换为大写字母。这个标签不会努力让 “琐碎的单词” 保持小写。

例如:

  1. {{ value|title }}

如果 value"my FIRST post",则输出将是 "My First Post"

truncatechars

如果一个字符串的长度超过指定的字符数,则截断它。截断后的字符串将以一个可翻译的省略号(“…”)结束。

参数: 要截断的字符数

例如:

  1. {{ value|truncatechars:7 }}

如果 value"Joel is a slug",则输出将是 "Joel i…"

truncatechars_html

类似于 truncatechars,只是它能识别 HTML 标签。任何在字符串中打开但在截断点之前没有关闭的标签都会在截断后立即关闭。

例如:

  1. {{ value|truncatechars_html:7 }}

如果 value"<p>Joel is a slug</p>",则输出将是 "<p>Joel i…</p>"

HTML 内容中的新行将被保留。

输入字符串的大小

处理大型、可能格式不正确的 HTML 字符串可能会消耗大量资源,影响服务性能。truncatechars_html 限制输入字符串的长度为前五百万个字符。

Changed in Django 3.2.22:

在旧版本中,处理超过五百万个字符的字符串。

truncatewords

在一定字数后截断字符串。

参数: 要在之后截断的字数

例如:

  1. {{ value|truncatewords:2 }}

如果 value"Joel is a slug",则输出将是 "Joel is …"

字符串内的新行将被删除。

truncatewords_html

类似于 truncatewords,只是它能识别 HTML 标签。任何在字符串中打开的标签,如果在截断点之前没有关闭,则会在截断后立即关闭。

这比 truncatewords 效率低,所以只能在传递 HTML 文本时使用。

例如:

  1. {{ value|truncatewords_html:2 }}

如果 value"<p>Joel is a slug</p>",则输出将是 "<p>Joel is …</p>"

HTML 内容中的新行将被保留。

输入字符串的大小

处理大型、可能格式不正确的 HTML 字符串可能会消耗大量资源,影响服务性能。truncatewords_html 限制输入字符串的长度为前五百万个字符。

Changed in Django 3.2.22:

在旧版本中,处理超过五百万个字符的字符串。

unordered_list

递归地接受一个自我嵌套的列表,并返回一个 HTML 无序列表 — 不包括 开启和关闭的 <ul> 标签。

假设列表的格式是正确的。例如,如果 var 包含 ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']],那么 {{ var|unordered_list }} 将返回:

  1. <li>States
  2. <ul>
  3. <li>Kansas
  4. <ul>
  5. <li>Lawrence</li>
  6. <li>Topeka</li>
  7. </ul>
  8. </li>
  9. <li>Illinois</li>
  10. </ul>
  11. </li>

upper

将一个字符串转换为全大写。

例如:

  1. {{ value|upper }}

如果 value"Joel is a slug",则输出将是 "JOEL IS A SLUG"

urlencode

转义一个值用于 URL。

例如:

  1. {{ value|urlencode }}

如果 value"https://www.example.org/foo?a=b&c=d",则输出将是 "https%3A//www.example.org/foo%3Fa%3Db%26c%3Dd"

可以提供一个可选的参数,包含不应该被转义的字符。

如果没有提供,将假定 ‘/‘ 字符是安全的。当应该转义 所有 字符时,可以提供一个空字符串。例如:

  1. {{ value|urlencode:"" }}

如果 value"https://www.example.org/",则输出将是 "https%3A%2F%2Fwww.example.org%2F"

urlize

将文本中的 URL 和电子邮件地址转换为可点击的链接。

This template tag works on links prefixed with http://, https://, or www.. For example, https://djangocon.eu will get converted but djangocon.eu won’t.

它还支持以原始顶级域(.com.edu.gov.int.mil.net.org)之一结尾的纯域链接。例如,djangoproject.com 被转换。

链接可以有尾部的标点符号(句号、逗号、闭括号),也可以有前面的标点符号(开头的小括号),urlize 仍然会做正确的事情。

urlize 产生的链接有一个 rel="nofollow" 属性。

例如:

  1. {{ value|urlize }}

如果 value"Check out www.djangoproject.com",则输出将是 "Check out <a href="http://www.djangoproject.com" rel="nofollow">www.djangoproject.com</a>"

除了网页链接,urlize 还将电子邮件地址转换为 mailto: 链接。如果 value"Send questions to foo@example.com",输出将是 "Send questions to <a href="mailto:foo@example.com">foo@example.com</a>"

urlize 过滤器还可以使用一个可选的参数 autoescape。如果 autoescapeTrue,则链接文本和 URL 将使用 Django 内置的 escape 过滤器进行转义。autoescape 的默认值是 True

备注

如果 urlize 应用于已经包含 HTML 标记的文本,或者应用于包含单引号(')的电子邮件地址,那么事情就不会像预期的那样进行。只对纯文本应用此过滤器。

urlizetrunc

urlize 一样,将 URL 和电子邮件地址转换为可点击的链接,但会截断长于给定字符限制的 URL。

参数: 链接文本应截断的字符数,包括必要时添加的省略号。

例如:

  1. {{ value|urlizetrunc:15 }}

如果 value"Check out www.djangoproject.com",则将输出 'Check out <a href="http://www.djangoproject.com" rel="nofollow">www.djangoproj…</a>'

urlize 一样,这个过滤器只能应用于纯文本。

wordcount

返回单词的数量。

例如:

  1. {{ value|wordcount }}

如果 value"Joel is a slug",则输出将是 4

wordwrap

以指定的行长度包装文字。

参数: 包裹文本的字符数

例如:

  1. {{ value|wordwrap:5 }}

如果 valueJoel is a slug,输出将是:

  1. Joel
  2. is a
  3. slug

yesno

TrueFalse 和(可选的) None 值映射到字符串 “yes”、“no”、“maybe” 或以逗号分隔的列表形式传递的自定义映射,并根据值返回其中一个字符串。

例如:

  1. {{ value|yesno:"yeah,no,maybe" }}
参数输出
True yes
True“yeah,no,maybe”yeah
False“yeah,no,maybe”no
None“yeah,no,maybe”maybe
None“yeah,no”no (如果没有给出 None 的映射,则将 None 转换为 False

国际化标签和过滤器

Django 提供了模板标签和过滤器来控制模板中的 国际化 的各个环节。它们允许对翻译、格式化和时区转换进行细化控制。

i18n

该库允许在模板中指定可翻译的文本。要启用它,请将 USE_I18N 设置为 True,然后用 {% load i18n %} 加载它。

参见 在模板代码中国际化

l10n

这个库提供了在模板中本地化值的控制。你只需要使用 {% load l10n %} 来加载这个库。

参见 在模板中控制本地化

tz

这个库提供了对模板中时区转换的控制。和 l10n 一样,你只需要使用 {% load tz %} 加载该库,但你通常也会将 USE_TZ 设置为 True,这样就会默认转换为当地时间。

参见 模板中有时区的输出

其他标签和过滤器库

Django 自带了一些其他的模板标签库,你必须在你的 INSTALLED_APPS 配置中明确启用,并在你的模板中用 {% load %} 标签启用。

django.contrib.humanize

一组 Django 模板过滤器,用于给数据添加 “人情味”。参见 django.contrib.humanize

static

static

要链接到保存在 STATIC_ROOT 中的静态文件,Django 提供了一个 static 模板标签。如果安装了 django.contrib.staticfiles 应用程序,该标签将使用 STORAGES 中由 staticfiles 指定的存储的 url() 方法来提供文件。例如:

  1. {% load static %}
  2. <img src="{% static 'images/hi.jpg' %}" alt="Hi!">

它还可以使用标准的上下文变量,例如,假设一个 user_stylesheet 变量被传递给模板:

  1. {% load static %}
  2. <link rel="stylesheet" href="{% static user_stylesheet %}" media="screen">

如果你想获取静态 URL 而不显示它,可以使用稍微不同的调用方式:

  1. {% load static %}
  2. {% static "images/hi.jpg" as myphoto %}
  3. <img src="{{ myphoto }}">

使用 Jinja2 模板?

参见 Jinja2,了解如何在 Jinja2 中使用 static 标签。

get_static_prefix

你应该更喜欢使用 static 模板标签,但是如果你需要更多地控制 STATIC_URL 被注入到模板的位置和方式,你可以使用 get_static_prefix 模板标签:

  1. {% load static %}
  2. <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!">

还有一种第二种形式,如果你需要多次使用该值,可以使用它来避免额外的处理:

  1. {% load static %}
  2. {% get_static_prefix as STATIC_PREFIX %}
  3. <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!">
  4. <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!">

get_media_prefix

类似于 get_static_prefixget_media_prefix 用媒体前缀 MEDIA_URL 填充一个模板变量,例如:

  1. {% load static %}
  2. <body data-media-url="{% get_media_prefix %}">

通过将值存储在数据属性中,我们可以确保在 JavaScript 上下文中使用该值时适当地进行转义。