在 Django Web 开发中,模板系统扮演着至关重要的角色,它负责将数据渲染成用户看到的 HTML 页面。然而,从视图传递到模板的数据并不总是符合最终的显示要求。有时需要对这些数据进行格式化、转换或计算。Django 模板过滤器(Filters)正是为此而生,它们提供了一种简洁而强大的方式,在模板层面直接修改变量的显示输出,而无需修改视图逻辑。
什么是模板过滤器?
模板过滤器本质上是简单的函数,它们接收一个变量作为输入,对其进行处理,然后返回转换后的结果。过滤器的主要目的是在表示层(模板)处理数据显示格式,保持视图逻辑的纯粹性。其基本语法非常直观,通过在变量名后使用管道符 |
和过滤器名称来调用。
例如,如果有一个名为 name
的变量,其值为 "Django Framework",我们想将其显示为全小写,可以使用 lower
过滤器:
{{ name|lower }}
渲染后的输出将是 "django framework"。
过滤器还可以接受参数,参数跟在过滤器名称后面,用冒号 :
分隔。
例如,truncatewords
过滤器用于截断文本至指定单词数,它接受一个整数作为参数:
{{ long_text|truncatewords:15 }}
这将显示 long_text
变量的前 15 个单词,并在末尾添加省略号(...)。
常用内置过滤器实例
Django 内置了大量实用的过滤器,覆盖了常见的文本处理、日期格式化、列表操作等需求。下面介绍几个常用的过滤器及其用法。
文本处理过滤器
lower
/upper
: 将字符串转换为全小写或全大写。- 案例: 假设视图传递了一个
title = "Welcome to Django"
。 - 模板:
<h1>{{ title|upper }}</h1>
- 输出:
<h1>WELCOME TO DJANGO</h1>
- 案例: 假设视图传递了一个
capfirst
: 将字符串的第一个字母大写。- 案例: 假设
message = "hello world"
。 - 模板:
<p>{{ message|capfirst }}</p>
- 输出:
<p>Hello world</p>
- 案例: 假设
truncatewords
: 按单词数截断字符串。- 案例: 假设
article_summary = "这是一个非常长的文章摘要,它包含了很多很多单词..."
。 - 模板:
<p>{{ article_summary|truncatewords:10 }}</p>
- 输出:
<p>这是一个非常长的文章摘要,它包含了很多很多 ...</p>
- 案例: 假设
truncatechars
: 按字符数截断字符串。- 案例: 假设
product_code = "ABCDEFGHIJKLMN"
。 - 模板:
<span>Code: {{ product_code|truncatechars:8 }}</span>
- 输出:
<span>Code: ABCDE...</span>
- 案例: 假设
数值与列表过滤器
length
: 返回变量的长度(适用于字符串、列表、字典等)。- 案例: 假设
items = ['apple', 'banana', 'cherry']
。 - 模板:
<p>购物车中有 {{ items|length }} 件商品。</p>
- 输出:
<p>购物车中有 3 件商品。</p>
- 案例: 假设
add
: 将参数值添加到变量值上。它会尝试将两者都转换为整数进行加法。如果转换失败,会尝试进行拼接(类似字符串或列表)。- 案例: 假设
current_year = 2024
。 - 模板:
<p>明年是:{{ current_year|add:"1" }}</p>
- 输出:
<p>明年是:2025</p>
- 案例: 假设
base_url = "/static/"
和image_path = "img/logo.png"
。 - 模板:
<img src="{{ base_url|add:image_path }}">
- 输出:
<img src="/static/img/logo.png">
- 案例: 假设
filesizeformat
: 将字节数格式化为人类可读的文件大小(如 KB, MB, GB)。- 案例: 假设
file_size = 1234567
(字节)。 - 模板:
<span>文件大小: {{ file_size|filesizeformat }}</span>
- 输出:
<span>文件大小: 1.2 MB</span>
- 案例: 假设
日期与时间过滤器
date
: 根据给定格式格式化日期或日期时间对象。格式化字符遵循 PHP 的date()
函数语法。- 案例: 假设
publish_date
是一个datetime
对象,表示 2024 年 7 月 26 日 15:30。 - 模板:
<p>发布于:{{ publish_date|date:"Y-m-d H:i" }}</p>
- 输出:
<p>发布于:2024-07-26 15:30</p>
- 模板:
<p>发布日期:{{ publish_date|date:"SHORT_DATE_FORMAT" }}</p>
(使用 Django settings 中的格式) - 输出: (取决于
SHORT_DATE_FORMAT
设置,例如<p>发布日期:07/26/2024</p>
)
- 案例: 假设
安全与默认值过滤器
default
: 如果变量的值评估为False
(例如,空字符串、空列表、None
、False
),则使用提供的默认值。- 案例: 假设
user_bio
可能为空。 - 模板:
<p>简介:{{ user_bio|default:"该用户很懒,什么也没留下。" }}</p>
- 输出: 如果
user_bio
为空或None
,则输出<p>简介:该用户很懒,什么也没留下。</p>
- 案例: 假设
safe
: 标记一个字符串为安全的,不进行 HTML 转义。请谨慎使用此过滤器,仅用于你确定内容来源可靠且不包含恶意代码的情况,否则可能导致跨站脚本(XSS)攻击。- 案例: 假设
html_content
包含<p>这是<strong>加粗</strong>文本。</p>
且你信任其来源。 - 模板:
<div>{{ html_content|safe }}</div>
- 输出:
<div><p>这是<strong>加粗</strong>文本。</p></div>
(HTML 被直接渲染) - 对比 (无
safe
):<div>{{ html_content }}</div>
- 输出 (无
safe
):<div><p>这是<strong>加粗</strong>文本。</p></div>
(HTML 被转义)
- 案例: 假设
过滤器链
过滤器可以链接使用,即一个过滤器的输出可以作为下一个过滤器的输入。
- 案例: 假设
comment = " 这是一个需要清理和截断的评论文本 "
。 - 模板:
<p>{{ comment|striptags|truncatewords:5|lower }}</p>
striptags
: 移除所有 HTML 标签。truncatewords:5
: 截断到 5 个单词。lower
: 转换为小写。
- 输出:
<p>这是一个需要清理和截断的 ...</p>
(注意:实际输出会先移除前后空格,然后截断再转小写)
过滤器工作流程图示
下面使用 Mermaid 图示简单展示一个变量经过过滤器的处理流程:
这个图示说明了当模板引擎遇到 0
语法时,它会找到对应的过滤器函数,将变量传递给该函数,并将函数的返回值用于最终的渲染输出。
小结
Django 模板过滤器是模板语言中一个极其有用的特性。它们允许开发者在不修改后端视图代码的情况下,方便地调整和格式化前端显示的数据。通过灵活运用内置过滤器,以及在需要时创建自定义过滤器,可以极大地提高模板开发效率,并保持代码的清晰分离。掌握过滤器的使用是成为一名高效 Django 开发者的关键一步。