Django进阶之自定义标签和过滤器
简介
Django的模板语言附带了各种内置标签和过滤器,旨在满足应用程序的表示逻辑需求。不过,有时候可能会发现自己需要的功能不在核心模板原语集范围内。这是我们可以通过使用Python定义,自定义标签和过滤器来扩展模板引擎,然后使用标签将它们提供给模板。{% load %}
自定义标签和过滤器需要注意一下几点:
- 在settings.py文件中注册当前app,不然django无法找到自定义的simple_tag.
- 在app中创建templatetags模块(模块名只能是templatetags)
- 创建任意 .py 文件,如:custom_tags.py / custom_filter.py
注意:添加templatetags 模块后,需要重新启动服务器,然后才能在模板中使用标签或过滤器。
from django import template register = template.Library() # 注册自定义标签,是模块成为有效的标签库,register的名字是固定的,不可改变 # template.Library中注册了所有标签和过滤器。因此,在模块的顶部需要添加以上两行代码
编写自定义过滤器
自定义过滤器是一个带有一个或两个参数的Python函数:
- 变量(输入)的值 , 不一定是一个字符串。
- 参数的值 ,这可以有一个默认值,或完全省略。
自定义过滤器:
def cut(value, arg):
''' 从value中删除所有的arg '''
return value.replace(arg, '')
def reverse(value): # 只接收一个参数.
""" 将字符串反转 """
return value[::-1]
注册自定义过滤器:
register.filter('cut', cut)
register.filter('reverse', reverse)
该Library.filter()方法有两个参数:
- 过滤器的名称 ,一个字符串。
- 编译函数, 一个Python函数。
也可以使用register.filter()作为装饰器:
@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg, '')
@register.filter
def reverse(value):
return value[::-1]
如果不指定name参数,filter后面的"()"也可以忽略。Django将使用该函数的名字作为过滤器名称。
register.filter()还接受三个关键字参数, is_safe,needs_autoescape,和expects_localtime。
过滤器使用示例:
在模板中使用自定义过滤器或标签需要加载自定义过滤器或标签模块(python文件的名称)
{% load custom_filter %}
{{ value|cut:"0" }}
示例:
def custom_tags(request): value = '120306' string = 'python' return render(request, 'index.html', {'value': value, 'string': string})
<body> <h2>Index</h2> {% load tags %} {{ value|cut:'0'}} <br> {{ string|reverse }} </body>
结果:

期望字符串的模板过滤器
如果想编写一个只需要字符串作为第一个参数的过滤器,那么就应该使用装饰器stringfilter。它将在传递给函数之前将对象转换为字符串。
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
@register.filter
@stringfilter
def reverse(value):
return value[::-1]
这样,我们就可以将一个整数传递给这个过滤器,并且不会导致TypeError: 'int' object is not subscriptable(因为整数没有索引)。
过滤器和自动转义
在编写自定义过滤器时,我们应该考虑过滤器如何与Django的自动转义行为进行交互。
自定义模板标签
标签比过滤器更复杂,因为标签可以做任何事情。Django提供了许多快捷方式,可以更轻松地编写大多数类型的标签。
简单标签
许多模板标签需要许多参数 ——字符串或模板变量 ,并在完成一些基于输入参数和外部信息的处理后返回结果。例如, current_time标签可能会接受格式字符串,并将时间作为字符串格式化。
为了简化这些类型的标签的创建,Django提供了一个辅助函数, simple_tag。这个函数是一个方法 django.template.Library,它接受一个接受任意数量参数的函数,将它包装在一个render函数和上面提到的其他必要部分中,并将其注册到模板系统中。
import datetime
from django import template
register = template.Library()
@register.simple_tag
def current_time(format_string):
return datetime.datetime.now().strftime(format_string)
关于simple_tag 辅助函数几件值得注意的事项︰
- 检查所需参数的数量等等,在我们的函数调用的时刻已经完成,所以我们不需要做了。
- 参数(如果有)的引号都已经被截掉,所以我们收到的只是一个普通字符串。
- 如果该参数是一个模板变量,传递给我们的函数是当前变量的值,不是变量本身。

浙公网安备 33010602011771号