内置模板标签和过滤器

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

内置标签参考

autoescape

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

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

唯一的例外是那些已经被标记为 “安全” 的变量,这些变量可以是被填充变量的代码标记的,也可以是被应用了 safeescape 过滤器的。

示例用法:

{% autoescape on %}
    {{ body }}
{% endautoescape %}

block

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

comment

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

示例用法:

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

comment 标签不能嵌套。

csrf_token

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

cycle

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

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

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

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

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

{% for o in some_list %}
    <tr class="{% cycle rowvalue1 rowvalue2 %}">
        ...
    </tr>
{% endfor %}

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

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

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

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

在某些情况下,你可能想引用一个周期的当前值,而不是前进到下一个值。要做到这一点,请使用 “as” 给 {% cycle %} 标签命名,比如:

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

从那时起,你可以通过引用循环名称作为上下文变量,在模板中任何地方插入循环的当前值。如果你想把循环移动到下一个值,独立于原来的 cycle 标签,你可以使用另一个 cycle 标签,并指定变量的名称。所以,下面的模板:

<tr>
    <td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
    <td class="{{ rowcolors }}">...</td>
</tr>
<tr>
    <td class="{% cycle rowcolors %}">...</td>
    <td class="{{ rowcolors }}">...</td>
</tr>

将会输出:

<tr>
    <td class="row1">...</td>
    <td class="row1">...</td>
</tr>
<tr>
    <td class="row2">...</td>
    <td class="row2">...</td>
</tr>

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

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

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

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

当在循环定义上使用 silent 关键字时,silent 自动适用于该特定循环标记的所有后续使用。以下模板将 输出任何东西,即使第二次调用 {% cycle %} 并没有指定 silent

{% cycle 'row1' 'row2' as rowcolors silent %}
{% cycle rowcolors %}

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

debug

输出整体的调试信息,包括当前上下文和导入的模块。

extends

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

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

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

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

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

dir1/
    template.html
    base2.html
    my/
        base3.html
base1.html

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

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

filter

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

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

示例用法:

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

注解

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

firstof

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

示例用法:

{% firstof var1 var2 var3 %}

这相当于:

{% if var1 %}
    {{ var1 }}
{% elif var2 %}
    {{ var2 }}
{% elif var3 %}
    {{ var3 }}
{% endif %}

你也可以在所有传递的变量都是 False 的情况下使用一个字符串作为后备值:

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

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

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

或者如果只对一些变量进行转义,可以使用:

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

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

for

循环浏览数组中的每个项目,使该项目在上下文变量中可用。例如,要显示 athlete_list 中提供的运动员列表:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

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

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

{% for x, y in points %}
    There is a point at {{ x }},{{ y }}
{% endfor %}

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

{% for key, value in data.items %}
    {{ key }}: {{ value }}
{% 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 在嵌套循环中,指向当前循环的上级循环

for ... empty

当传递到 for 标签中的数组不存在或为空时,可以使用 {% empty %} 标签来指定输出的内容:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% empty %}
    <li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>

上面的代码与下面的代码是等同的,但上面的代码更简短,更清晰,也可能更快。

<ul>
  {% if athlete_list %}
    {% for athlete in athlete_list %}
      <li>{{ athlete.name }}</li>
    {% endfor %}
  {% else %}
    <li>Sorry, no athletes in this list.</li>
  {% endif %}
</ul>

if

{% if %} 标签会判断给定的变量,当变量为 True 时(比如存在、非空、非布尔值 False),就会输出块内的内容:

{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}

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

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

布尔操作

if 标签可以使用 andornot 来测试一些变量或取反某个变量:

{% if athlete_list and coach_list %}
    Both athletes and coaches are available.
{% endif %}

{% if not athlete_list %}
    There are no athletes.
{% endif %}

{% if athlete_list or coach_list %}
    There are some athletes or some coaches.
{% endif %}

{% if not athlete_list or coach_list %}
    There are no athletes or there are some coaches.
{% endif %}

{% if athlete_list and not coach_list %}
    There are some athletes and absolutely no coaches.
{% endif %}

允许在同一标签中同时使用 andor 子句,andor 优先级高,例如:

{% if athlete_list and coach_list or cheerleader_list %}

将被解释为:

if (athlete_list and coach_list) or cheerleader_list

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

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

== 运算符

相等。例如:

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

不相等。例如:

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

小于。例如:

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

大于。例如:

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

小于等于。例如:

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

大于等于。例如:

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

包含其中。许多 Python 容器都支持这个运算符来测试给定值是否在容器中。下面是一些如何解释 x in y 的例子:

{% if "bc" in "abcdef" %}
  This appears since "bc" is a substring of "abcdef"
{% endif %}

{% if "hello" in greetings %}
  If greetings is a list or set, one element of which is the string
  "hello", this will appear.
{% endif %}

{% if user in users %}
  If users is a QuerySet, this will appear if user is an
  instance that belongs to the QuerySet.
{% endif %}
not in 操作符

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

is 运算符

对象检测。测试两个变量是否为同一个对象。例如:

{% if somevar is True %}
  This appears if and only if somevar is True.
{% endif %}

{% if somevar is None %}
  This appears if somevar is None, or if somevar is not found in the context.
{% endif %}
is not 运算符

对象检测后取反。测试两个变量是否不是同一个对象。这是对 is 运算符的取反。例如:

{% if somevar is not True %}
  This appears if somevar is not True, or if somevar is not found in the
  context.
{% endif %}

{% if somevar is not None %}
  This appears if and only if somevar is not None.
{% endif %}

过滤器

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

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

复合表达式

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

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

(这完全是按照 Python 来的)。所以,例如,以下复杂的 if 标签:

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

...将被解释为:

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

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

比较运算符不能像在 Python 或数学符号中那样 “连锁”。例如,不能使用:

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

你应该使用:

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

ifequalifnotequal

3.1 版后已移除.

{% ifequal a b %} ... {% endifequal %} 是写 {% if a == b %} ... {% endif %} 的过时方式。同样,{% ifnotequal a b %} ... {% endifnotequal %}{% if a != b %} ... {% endif %} 取代。

ifchanged

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

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

  1. 根据之前的状态检查自己渲染的内容,只有在内容发生变化时才显示。例如,这将显示一个天数列表,如果它改变了,只显示月份:

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

    {% for date in days %}
        {% ifchanged date.date %} {{ date.date }} {% endifchanged %}
        {% ifchanged date.hour date.date %}
            {{ date.hour }}
        {% endifchanged %}
    {% endfor %}
    

ifchanged 标签也可以使用一个可选的 {% else %} 子句,如果值没有改变,就会显示:

{% for match in matches %}
    <div style="background-color:
        {% ifchanged match.ballot_id %}
            {% cycle "red" "blue" %}
        {% else %}
            gray
        {% endifchanged %}
    ">{{ match }}</div>
{% endfor %}

include

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

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

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

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

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

这个例子包含模板的内容,其名称包含在变量 template_name

{% include template_name %}

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

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

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

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

  • 模板:

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

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

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

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

如果你想只用所提供的变量(甚至不使用变量)来渲染上下文,请使用 only 选项。所包含的模板没有其他变量可用:

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

注解

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

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

Changed in Django 3.1:

增加了对可迭代对象作为模板名称的支持。

load

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

例如,下面的模板将加载所有在 somelibraryotherlibrary 中注册的标签和过滤器,这些标签和过滤器位于 package

{% load somelibrary package.otherlibrary %}

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

{% load foo bar from somelibrary %}

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

lorem

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

用法:

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

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

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

举例:

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

now

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

举例:

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

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

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

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

注解

传递的格式也可以是预定义的 DATE_FORMATDATETIME_FORMATSHORT_DATE_FORMATSHORT_DATETIME_FORMAT。预定义的格式可能会有所不同,这取决于当前的 locale 和是否启用了 本地格式化,例如:

It is {% now "SHORT_DATETIME_FORMAT" %}

你也可以使用 {% now "Y" as current_year %} 的语法将输出(作为字符串)存储在一个变量中。如果你想在模板标签中使用 {% now %},比如 blocktranslate,这就很有用。

{% now "Y" as current_year %}
{% blocktranslate %}Copyright {{ current_year }}{% endblocktranslate %}

regroup

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

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

cities = [
    {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
    {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
    {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
    {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
    {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]

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

  • 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 %} 标签按国家对城市列表进行分组。以下模板代码片段可以实现这一目的:

{% regroup cities by country as country_list %}

<ul>
{% for country in country_list %}
    <li>{{ country.grouper }}
    <ul>
        {% for city in country.list %}
          <li>{{ city.name }}: {{ city.population }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

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

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

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

因为 {% regroup %} 会产生 namedtuple() 对象,所以也可以把前面的例子写成:

{% regroup cities by country as country_list %}

<ul>
{% for country, local_cities in country_list %}
    <li>{{ country }}
    <ul>
        {% for city in local_cities %}
          <li>{{ city.name }}: {{ city.population }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

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

cities = [
    {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
    {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
    {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
    {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
    {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]

有了这个 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 过滤器对模板中的数据进行排序,如果你的数据是在字典列表中:

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

对其他属性进行分组

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

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

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

{% regroup cities by get_country_display as country_list %}

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

resetcycle

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

用法示例:

{% for coach in coach_list %}
    <h1>{{ coach.name }}</h1>
    {% for athlete in coach.athlete_set.all %}
        <p class="{% cycle 'odd' 'even' %}">{{ athlete.name }}</p>
    {% endfor %}
    {% resetcycle %}
{% endfor %}

这个例子会返回这样的HTML:

<h1>José Mourinho</h1>
<p class="odd">Thibaut Courtois</p>
<p class="even">John Terry</p>
<p class="odd">Eden Hazard</p>

<h1>Carlo Ancelotti</h1>
<p class="odd">Manuel Neuer</p>
<p class="even">Thomas Müller</p>

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

你还可以重置命名的循环标签:

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

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

spaceless

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

用法示例:

{% spaceless %}
    <p>
        <a href="foo/">Foo</a>
    </p>
{% endspaceless %}

这个例子会返回这样的HTML:

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

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

{% spaceless %}
    <strong>
        Hello
    </strong>
{% endspaceless %}

templatetag

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

由于模板系统没有 “转义” 的概念,所以要显示模板标签中使用的一个位,必须使用 {% templatetag %} 标签。

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

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

示例用法:

{% templatetag openblock %} url 'entry_list' {% templatetag closeblock %}

url

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

这是在不违反 DRY 原则的情况下,通过在模板中硬编码 URL 来输出链接的方法:

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

第一个参数是一个 URL 模式名称。它可以是一个引号文字或任何其他上下文变量。其他参数是可选的,应该是以空格分隔的值,这些值将在 URL 中作为参数使用。上面的例子显示的是传递位置参数。另外,你也可以使用关键字语法:

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

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

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

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

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

path('clients/', include('project_name.app_name.urls'))

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

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

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

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

如果你想在不显示的情况下检索一个 URL,你可以使用一个稍微不同的调用:

{% url 'some-url-name' arg arg2 as the_url %}

<a href="{{ the_url }}">I'm linking to {{ the_url }}</a>

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

如果缺少视图,这种 {% url ... as var %} 语法 不会 引起错误。在实践中,你会用它来链接到可选的视图:

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

如果你想检索一个命名空间的 URL,请指定完全限定的名称:

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

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

警告

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

verbatim

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

常见的用法是允许 JavaScript 模板层与 Django 的语法发生碰撞。例如:

{% verbatim %}
    {{if dying}}Still alive.{{/if}}
{% endverbatim %}

你也可以指定一个特定的结束标签,允许使用 {% endverbatim %} 作为未渲染内容的一部分:

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

widthratio

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

例子:

<img src="bar.png" alt="Bar"
     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 中,它可能是有用的,像这样:

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

with

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

例子:

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

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

你可以指定一个以上的上下文变量:

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

注解

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

内置过滤器参考

add

将参数添加到值中。

例子:

{{ value|add:"2" }}

如果 value4,那么输出将是 6

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

例如,如果我们有:

{{ first|add:second }}

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

警告

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

addslashes

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

例子:

{{ value|addslashes }}

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

capfirst

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

例子:

{{ value|capfirst }}

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

center

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

例子:

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

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

cut

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

例子:

{{ value|cut:" " }}

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

date

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

Uses a similar format to PHP's date() function with some differences.

注解

这些格式字符在模板之外的 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 Year, 2 digits with leading zeros. '00' to '99'
Y 年,4 位数字。 '1999'
L 是否为闰年的布尔值。 TrueFalse
o ISO-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
日期/时间    
c ISO 8601 format. (Note: unlike other formatters, such as "Z", "O" or "r", the "c" formatter will not add timezone offset if value is a naive datetime (see datetime.tzinfo). 2008-01-02T10:30:00.000123+02:002008-01-02T10:30:00.000123 如果日期时间是本地的
r RFC 5322 格式的日期。 'Thu, 21 Dec 2000 16:01:07 +0200'
U 自 Unix 纪元(1970 年 1 月 1 日 00:00:00 UTC)以来的秒数。  

例子:

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

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

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

假设 USE_L10NTrueLANGUAGE_CODE 为例如 "es",那么对于:

{{ value|date:"SHORT_DATE_FORMAT" }}

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

当不使用格式字符串时,使用 DATE_FORMAT 格式指定器。假设设置与前一个例子相同:

{{ value|date }}

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

你可以将 datetime 过滤器结合起来,以呈现一个 datetime 值的完整表示。例如:

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

default

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

例子:

{{ value|default:"nothing" }}

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

default_if_none

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

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

例子:

{{ value|default_if_none:"nothing" }}

如果 valueNone,则输出为 nothing

dictsort

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

例子:

{{ value|dictsort:"name" }}

如果 value 是:

[
    {'name': 'zed', 'age': 19},
    {'name': 'amy', 'age': 22},
    {'name': 'joe', 'age': 31},
]

那么输出将是:

[
    {'name': 'amy', 'age': 22},
    {'name': 'joe', 'age': 31},
    {'name': 'zed', 'age': 19},
]

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

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

如果 books 是:

[
    {'title': '1984', 'author': {'name': 'George', 'age': 45}},
    {'title': 'Timequake', 'author': {'name': 'Kurt', 'age': 75}},
    {'title': 'Alice', 'author': {'name': 'Lewis', 'age': 33}},
]

那么输出将是:

* Alice (Lewis)
* 1984 (George)
* Timequake (Kurt)

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

{{ value|dictsort:0 }}

如果 value 是:

[
    ('a', '42'),
    ('c', 'string'),
    ('b', 'foo'),
]

那么输出将是:

[
    ('a', '42'),
    ('b', 'foo'),
    ('c', 'string'),
]

你必须以整数而不是字符串的形式传递索引。以下情况会产生空的输出:

{{ values|dictsort:"0" }}

dictsortreversed

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

divisibleby

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

例子:

{{ value|divisibleby:"3" }}

如果 value21,则输出为 True

escape

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

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

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

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

{% autoescape off %}
    {{ title|escape }}
{% endautoescape %}

escapejs

在 JavaScript 字符串中使用的转义字符。这并不能使字符串安全地用于 HTML 或 JavaScript 模板字元,但可以保护你在使用模板生成 JavaScript/JSON 时避免语法错误。

例子:

{{ value|escapejs }}

如果 value"testing\r\njavascript 'string\" <b> escaping </b>",则输出为 "testing\\u000D\\u000Ajavascript \\u0027string\\u0022 \\u003Cb\\u003Eescaping\\u003C/b\\u003E"

filesizeformat

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

例子:

{{ value|filesizeformat }}

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

文件大小和 SI 单位

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

first

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

例子:

{{ 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

If the argument passed to floatformat has the g suffix, it will force grouping by the THOUSAND_SEPARATOR for the active locale. For example, when the active locale is en (English):

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

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

Changed in Django 3.1:

在旧版本中,对于四舍五入为零的负数,会返回一个负零 -0

Changed in Django 3.2:

The g suffix to force grouping by thousand separators was added.

force_escape

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

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

{% autoescape off %}
    {{ body|linebreaks|force_escape }}
{% endautoescape %}

get_digit

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

例子:

{{ value|get_digit:"2" }}

如果 value123456789,则输出为 8

iriencode

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

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

例子:

{{ value|iriencode }}

如果 value"?test=1&me=2",则输出为 "?test=1&amp;me=2"

join

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

例子:

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

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

json_script

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

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

例子:

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

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

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

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

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

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

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

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

last

返回列表中的最后一项。

例子:

{{ value|last }}

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

length

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

例子:

{{ value|length }}

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

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

length_is

如果值的长度是参数,则返回 True,否则返回 False

例子:

{{ value|length_is:"4" }}

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

linebreaks

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

例子:

{{ value|linebreaks }}

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

linebreaksbr

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

例子:

{{ value|linebreaksbr }}

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

linenumbers

显示带有行号的文本。

例子:

{{ value|linenumbers }}

如果 value 是:

one
two
three

输出将是:

1. one
2. two
3. three

ljust

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

参数: 字段大小

例子:

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

如果 valueDjango,则输出为 "Django    "

lower

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

例子:

{{ value|lower }}

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

make_list

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

例子:

{{ value|make_list }}

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

phone2numeric

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

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

例子:

{{ value|phone2numeric }}

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

pluralize

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

举例:

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

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

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

举例:

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

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

举例:

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

注解

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

pprint

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

random

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

例子:

{{ value|random }}

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

rjust

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

参数: 字段大小

例子:

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

如果 valueDjango,输出将是 "    Django"

safe

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

注解

如果你是链式过滤器,在 safe 之后应用的过滤器会使内容再次不安全。例如,下面的代码按原样打印变量,未转义:

{{ var|safe|escape }}

safeseq

safe 过滤器应用于序列的每个元素。与其他对序列进行操作的过滤器,如 join 一起使用。例如:

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

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

slice

返回列表的一个片段。

Uses the same syntax as Python's list slicing. See https://diveinto.org/python3/native-datatypes.html#slicinglists for an introduction.

举例:

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

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

slugify

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

例子:

{{ value|slugify }}

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

stringformat

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

例子:

{{ value|stringformat:"E" }}

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

striptags

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

例子:

{{ value|striptags }}

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

没有安全保证

请注意,striptags 并不能保证它的输出是 HTML 安全的,特别是对于非有效的 HTML 输入。所以 永远不要 应用 safe 过滤器到 striptags 的输出。如果你正在寻找更强大的东西,你可以使用 bleach Python 库,特别是它的 clean 方法。

time

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

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

例子:

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

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

请注意,如果你想使用 “原始” 值,你可以对格式字符串进行反斜杠转义。在这个例子中,“h” 和 “m” 都被反斜杠转义了,因为如果不这样做,每一个都是一个格式字符串,分别显示小时和月份:

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

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

另一个例子:

假设 USE_L10NTrueLANGUAGE_CODE 为例如 "de",那么对于:

{{ 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 格式指定符:

{{ value|time }}

同为:

{{ value|time:"TIME_FORMAT" }}

timesince

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

取一个可选参数,该参数是一个变量,包含作为比较点的日期(如果没有该参数,比较点是 现在 )。例如,如果 blog_date 是代表 2006 年 6 月 1 日午夜的日期实例,comment_date 是 2006 年 6 月 1 日 08:00 的日期实例,那么下面将返回 “8 hours”:

{{ 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 week”:

{{ conference_date|timeuntil:from_date }}

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

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

title

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

例子:

{{ value|title }}

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

truncatechars

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

参数: 要截断的字符数

例子:

{{ value|truncatechars:7 }}

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

truncatechars_html

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

例子:

{{ value|truncatechars_html:7 }}

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

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

truncatewords

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

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

例子:

{{ value|truncatewords:2 }}

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

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

truncatewords_html

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

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

例子:

{{ value|truncatewords_html:2 }}

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

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

unordered_list

递归地接受一个自嵌套列表,并返回一个 HTML 无序列表—— 没有 打开和关闭 <ul> 标签。

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

<li>States
<ul>
        <li>Kansas
        <ul>
                <li>Lawrence</li>
                <li>Topeka</li>
        </ul>
        </li>
        <li>Illinois</li>
</ul>
</li>

upper

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

例子:

{{ value|upper }}

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

urlencode

转义一个值用于 URL。

例子:

{{ value|urlencode }}

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

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

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

{{ value|urlencode:"" }}

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

urlize

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

这个模板标签适用于以 http://`、``https://www. 为前缀的链接。例如,https://goo.gl/aia1t 会被转换,但 goo.gl/aia1t 不会。

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

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

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

例子:

{{ 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。

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

例子:

{{ value|urlizetrunc:15 }}

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

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

wordcount

返回单词的数量。

例子:

{{ value|wordcount }}

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

wordwrap

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

参数: 包裹文本的字符数

例子:

{{ value|wordwrap:5 }}

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

Joel
is a
slug

yesno

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

例子:

{{ 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 %} 加载该库,但你通常会将 USE_L10N 设置为 True,这样默认情况下本地化是有效的。

参见 在模板中控制本地化

tz

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

参见 模板中时区感知(aware)输出

其他标签和过滤器库

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

django.contrib.humanize

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

static

static

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

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

它还能够消耗标准的上下文变量,例如,假设一个 user_stylesheet 变量被传递给模板:

{% load static %}
<link rel="stylesheet" href="{% static user_stylesheet %}" type="text/css" media="screen">

如果你想检索一个静态的 URL 而不显示它,你可以使用一个稍微不同的调用:

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

使用 Jinja2 模板?

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

get_static_prefix

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

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

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

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!">
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!">

get_media_prefix

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

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

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

Back to Top