geekdoc-python-zh/docs/overiq/175.md

10 KiB
Raw Permalink Blame History

Django 的模板过滤器

原文:https://overiq.com/django-1-11/template-filters-in-django/

最后更新于 2020 年 7 月 27 日


Django 过滤器用于在变量渲染为 HTML 代码之前修改变量的值。要使用过滤器,请在变量名后键入管道字符(|)后跟过滤器名称。

{{ variable|filter_name }}

下过滤器

当应用于变量时,lower过滤器会将变量中的所有大写字符转换为等效的小写字符。例如:

<p>{{ name|lower }}</p>

如果name变量的值是"Tom Sawyer",那么上面的代码将产生下面的 HTML。

<p>tom sawyer</p>

上部过滤器

upper滤镜与lower滤镜完全相反。它会将变量中的所有字符转换为大写等效字符。例如:

<p>{{ name|upper }}</p>

如果name变量的值是"tom sawyer",那么上面的代码将产生下面的 HTML。

<p>TOM SAWYER</p>

capfirst 滤波器

capfirst过滤器仅将变量中的第一个字符转换为其大写等效字符。例如:

<p>{{ name|capfirst }}</p>

如果变量name包含"tom sawyer",那么上面的代码将产生下面的 HTML。

<p>Tom sawyer</p>

您也可以链接过滤器。例如:

<p>{{ name|lower|capfirst }}</p>

这里name变量首先被转换成小写字符,然后对结果应用capfirst过滤器。

标题过滤器

title过滤器将每个单词的第一个字母大写。例如:

<p>{{ name|title }}</p>

如果变量name包含"tom sawyer",那么上面的代码将产生下面的 HTML。

<p>Tom Sawyer</p>

长度过滤器

length过滤器决定数值的长度。它可以处理字符串、列表、字典和元组。例如:

<p>The length variable name is {{ name|length }}</p>

如果变量name包含"tom sawyer",那么上面的代码将产生下面的 HTML。

<p>The length variable name is 10</p>

截断词过滤器

truncatewords过滤器在一定数量的单词后截断(缩短)字符串。截断字符串后,它将...(称为省略号)附加到截断字符串的末尾。truncatewords是你可以传递论点的过滤器之一。将参数传递给筛选器类型冒号(:),后跟双引号内的参数("")。要将多个参数传递给过滤器,请使用逗号(,)分隔它们。truncatewords接受单个参数,表示后面要截断的字数。例如,要只输出博文的第一个10字,请执行以下操作:

<p>{{ post|truncatewords:"10" }}</p>

如果post变量定义为:

post = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu lectus ut lacus posuere fringilla id eu turpis."

上面的代码将产生下面的 HTML。

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu ...</p>

截断滤波器

truncatechars过滤器类似于truncatewords,但它不是按单词截断,而是按字符截断。如果字符串大于指定的字符数,它将截断字符串。就像truncatewords过滤器一样,截断字符串后truncatechars过滤器会将...(省略号)追加到截断的字符串中。例如:

{{ long_text|truncatechars:"10" }}

如果字符串大于10个字符,这将截断字符串并将...追加到末尾。

如果long_text包含"Lorem ipsum dolor sit amet, consectetur adipiscing elit",那么上面的代码会产生下面的 HTML。

<p>Lorem i...</p>

复数滤波器

pluralize过滤器用于处理后缀。让我们举个例子:

<p>You have {{ num }} products in your cart</p>

如果n1,那么我们要显示。

<p>You have 1 product in your cart</p>

另一方面,如果n10,那么我们想要显示。

<p>You have 10 products in your cart</p>

注意字符串products中的s

我们可以使用pluralize过滤器轻松处理这些情况。

<p>You have {{ num }} product{{ num|pluralize }} in your cart</p>

现在,如果num1,输出将是:

<p>You have 1 product in your cart</p>

如果num的值为100,则输出为:

<p>You have 100 products in your cart</p>

默认情况下pluralize过滤器将"s"追加到字符串中。然而,并不是所有的复数单词都以"s"结尾,有些也像tomatoes一样以"es"结尾。例如:

<p>I have {{ num }} tomato{{ num|pluralize }}</p>

如果num等于5,则输出上述代码:

<p>I have 5 tomatos</p>

当然,这是错误的。要提供替代后缀,您可以将参数传递给pluralize过滤器。例如:

<p>I have {{ num }} tomato{{ num|pluralize:"es" }}</p>

如果num等于5,输出将是:

<p>I have 5 tomatoes</p>

还有一些单词不是用简单的后缀来复数的,比如日记和日记,樱桃和樱桃等等。为了处理这种特殊情况,你必须提供单数和复数后缀作为pluralize过滤器的参数。例如:

<p>I have {{ num }} diar{{ num|pluralize:"y,ies" }}</p>

如果num1,输出将为:

<p>I have 1 diary</p>

如果num5,输出将为:

<p>I have 5 diaries</p>

日期过滤器

我们使用date过滤器来格式化datetime.datedatetime.datetime对象。date过滤器使用一些特殊的格式字符来格式化datetime.datedatetime.datetime对象。要格式化日期,将一串格式字符作为参数传递给date过滤器。例如,假设我们的上下文有一个名为nowdatetime.datetime对象,其定义如下:

now = datetime.datetime.now()

我们的模板包含以下代码:

<p>Today is {{ now }}</p>

如果我们不使用date过滤器,那么上面的代码会产生下面的 HTML。

<p>Today is Jan. 27, 2017, 4:28 p.m.</p>

以下是一些常用的格式字符串,可用于date过滤器:

性格;角色;字母 它有什么作用? 例子
d 使用两位数字打印一个月中的某一天 0131
D 使用三个字母打印星期几 Mon为周一,Tue为周二,以此类推
m 使用两位数字打印月份 01为 1 月,02为 2 月,依此类推
M 使用三个字母数字打印月份 Jan为 1 月,Feb为 2 月,依此类推
i 打印分钟 0059
h 以 12 小时格式打印小时数 0112
H 以 24 小时格式打印小时数 0023
s 打印秒数 0059
a 打印“上午”或“下午” a.m.p.m.
Y 使用完整的 4 位数字打印年份 20012014等等

让我们向日期过滤器添加一些格式字符,如下所示:

<p>Today is {{ now|date:"D d M Y" }}</p>

这将输出如下内容:

<p>Today is Fri 27 Jan 2017</p>

换行过滤器

linebreaks过滤器将字符串中的换行符转换为适当的 HTML。如果一个字符串有换行符它将被转换为<br/>,后面跟一个空行的换行符将被转换为</p>

{{ text|linebreak }}

请考虑以下示例:

例 1:

content = '''\
this is
a content
'''

{{ content|linebreaks }}

那么输出将是:

<p>this is<br />a test<br /></p>

在变量content中有两个换行符,第一个出现在单词is之后(第 2 行),第二个出现在单词content之后(第 3 行)。 linebreaks过滤器用<br />标签替换这些换行符,并将整个字符串包装在<p>标签中。

例 2:

content = '''\
this is

a test
'''

{{ content|linebreaks }}

那么输出将是:

<p>this is</p>

<p>a test<br /></p>

linebreaksbr 过滤器

linebreaksbr过滤器仅将字符串中的换行符转换为<br>标记。例如:

{{ text|linebreaksbr}}

现在如果text变量的值是"Filter string\n using linebreaksbr",输出将是:

Filter string<br /> using linebreaksbr

标签自动抓取

出于安全考虑Django 模板系统会自动为您进行转义。考虑以下示例:

假设变量my_code包含"<p>this is short para </p>",模板中的代码为:

{{ my_code }}

上面的代码将渲染为以下 HTML:

&lt;p&gt;THIS IS TEST&lt;/p&gt;

有两种方法可以关闭转义:

  1. safe过滤。
  2. autoescape过滤。

安全过滤器

{{ my_code|safe }}

这段代码将产生以下 HTML 输出:

<p>this is short para </p>

safe过滤器告诉 Django Template 系统my_code变量是安全的,不需要转义。

关闭转义的另一种方法是使用autoescape标记

标签自动抓取

autoescape标签允许您在模板中转义/隐藏大块内容。它接受 on 或 off 作为参数,指示自动转义在块中是否有效。

例如:

{% autoescape on %}
    {{ code_snippet }}
{% endautoescape %}

由于默认情况下 Django 模板系统会自动转义所有内容,因此您可能永远不需要使用上面的代码。相反,我们通常使用autoescape标签来关闭大部分内容的转义。例如:

{% autoescape off %}
    {{ heading }}
    {{ main_content }}
    {{ footer }}
{% endautoescape %}

逸出过滤器

escape过滤器将以下字符转换为其 HTML 实体。

  • "替换为&quot
  • '替换为&#39
  • &替换为&amp
  • <替换为&lt
  • >替换为&gt

由于 Django 模板系统会自动转义所有内容,您可能永远不会使用escape过滤器:例如:

my_code = "<p>this is short para</p>"

{{ my_code }}

与...相同

{{ my_code|escape }}

autoescape关闭,我们想要逃离内容时,这个滤镜的效用就发挥出来了。例如:

{% autoescape off %}
    {{ heading }}
    {{ main_content }}
    {{ footer }}
    {{ comments }}
{% endautoescape %}

这里可以假设变量headingmain_contentfooter的内容是安全的。但是comments变量不是这样。这就是为什么关闭comments变量的转义不是一个好主意。要在模板中转义comments变量,您可以执行以下操作:

{% autoescape off %}
    {{ heading }}
    {{ main_content }}
    {{ footer }}
    {{ comments|escape }}
{% endautoescape %}

首先,这是足够的过滤器。要查看过滤器的完整列表,请查看 Django 文档中的页面。