1. 创建过滤器文件结构
首先,你需要创建一个专门存放过滤器的应用或目录:
myapp/
├── __init__.py
├── templatetags/
│ ├── __init__.py
│ └── my_filters.py # 你的过滤器文件
├── models.py
└── views.py
重要:templatetags 目录必须命名为 templatetags,且必须包含 __init__.py 文件。
2. 编写自定义过滤器
在 my_filters.py 文件中:
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
# 基本过滤器示例
@register.filter
def multiply(value, arg):
"""将值乘以参数"""
try:
return float(value) * float(arg)
except (ValueError, TypeError):
return ''
# 带装饰器的字符串过滤器
@register.filter
@stringfilter
def reverse_string(value):
"""反转字符串"""
return value[::-1]
# 带名称的过滤器
@register.filter(name='cut')
def cut_string(value, arg):
"""移除字符串中的所有指定字符"""
return value.replace(arg, '')
# 布尔过滤器(返回True/False)
@register.filter
def is_upper(value):
"""检查字符串是否全为大写"""
return value.isupper()
# 带默认参数的过滤器
@register.filter
def truncate_chars(value, arg=20):
"""截断字符串到指定长度,添加省略号"""
if len(value) <= arg:
return value
return value[:arg] + '...'
# 处理日期的过滤器
@register.filter
def days_since(value):
"""计算从给定日期到现在的天数"""
from datetime import date
if not value:
return ''
delta = date.today() - value
return delta.days
# 处理列表的过滤器
@register.filter
def join_by(value, delimiter=', '):
"""用指定分隔符连接列表"""
if not value:
return ''
return delimiter.join(str(item) for item in value)
3. 注册和使用过滤器
方法一:装饰器方式(推荐)
@register.filter
def my_filter(value):
# 过滤器逻辑
return processed_value
方法二:函数调用方式
def my_filter(value):
# 过滤器逻辑
return processed_value
register.filter('filter_name', my_filter)
4. 在模板中使用
{% load my_filters %}
<!-- 基本使用 -->
<p>原始值: {{ number }}</p>
<p>乘以2: {{ number|multiply:2 }}</p>
<!-- 字符串处理 -->
<p>反转: {{ "hello"|reverse_string }}</p>
<p>移除空格: {{ text|cut:" " }}</p>
<!-- 链式调用 -->
<p>{{ text|cut:"a"|reverse_string }}</p>
<!-- 布尔过滤器 -->
{% if text|is_upper %}
<p>文本是大写的</p>
{% endif %}
5. 高级用法
安全的HTML过滤器
from django.utils.safestring import mark_safe
@register.filter(is_safe=True)
def highlight(value, search_term):
"""高亮显示搜索词"""
highlighted = value.replace(
search_term,
f'<span class="highlight">{search_term}</span>'
)
return mark_safe(highlighted)
接收多个参数的过滤器
@register.filter
def replace(value, arg1, arg2):
"""替换字符串中的字符"""
return value.replace(arg1, arg2)
# 在模板中使用:{{ text|replace:"old":"new" }}
分类标签过滤器
@register.filter
def get_item(dictionary, key):
"""从字典中获取值"""
return dictionary.get(key)
6. 在设置中注册(如果需要)
确保你的应用在 INSTALLED_APPS 中:
# settings.py
INSTALLED_APPS = [
# ...
'myapp', # 包含自定义过滤器的应用
# ...
]
注意事项
自动发现:Django会自动发现
templatetags 目录中的过滤器
重启服务器:添加新过滤器后需要重启开发服务器
导入顺序:确保过滤器文件没有循环导入
命名冲突:避免与内置过滤器重名
错误处理:在过滤器中添加适当的错误处理
调试技巧
如果过滤器不工作,可以检查:
templatetags 目录名是否正确
- 是否添加了
__init__.py 文件
- 是否在模板中正确加载
{% load my_filters %}
- 过滤器函数是否已注册
- 服务器是否已重启
通过自定义过滤器,你可以扩展Django模板的功能,创建可重用的模板逻辑组件。