Skip to content

Django 模板过滤器详解:轻松转换模板变量

在 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(例如,空字符串、空列表、NoneFalse),则使用提供的默认值。

    • 案例: 假设 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>&lt;p&gt;这是&lt;strong&gt;加粗&lt;/strong&gt;文本。&lt;/p&gt;</div> (HTML 被转义)

过滤器链

过滤器可以链接使用,即一个过滤器的输出可以作为下一个过滤器的输入。

  • 案例: 假设 comment = " 这是一个需要清理和截断的评论文本 "
  • 模板: <p>{{ comment|striptags|truncatewords:5|lower }}</p>
    • striptags: 移除所有 HTML 标签。
    • truncatewords:5: 截断到 5 个单词。
    • lower: 转换为小写。
  • 输出: <p>这是一个需要清理和截断的 ...</p> (注意:实际输出会先移除前后空格,然后截断再转小写)

过滤器工作流程图示

下面使用 Mermaid 图示简单展示一个变量经过过滤器的处理流程:

这个图示说明了当模板引擎遇到 0 语法时,它会找到对应的过滤器函数,将变量传递给该函数,并将函数的返回值用于最终的渲染输出。

小结

Django 模板过滤器是模板语言中一个极其有用的特性。它们允许开发者在不修改后端视图代码的情况下,方便地调整和格式化前端显示的数据。通过灵活运用内置过滤器,以及在需要时创建自定义过滤器,可以极大地提高模板开发效率,并保持代码的清晰分离。掌握过滤器的使用是成为一名高效 Django 开发者的关键一步。

参考资料