Django虽然为我们内置了六十多种过滤器,但是需求是各种各样的,总有一款你cover不到。不过没关系,Django为我们提供了自定义的机制,可以通过使用Python代码,自定义过滤器来扩展模板引擎,然后使用{% load %}标签。
Django对于自定义过滤器是有前置要求的,首先一条就是代码布局和文件组织。
第一步,在app中新建一个templatetags
包(名字固定,不能变,只能是这个),和views.py、models.py等文件处于同一级别目录下。这是一个包!不要忘记创建__init__.py
文件以使得该目录可以作为Python的包。
在添加templatetags包后,需要重新启动服务器,然后才能在模板中使用过滤器。
-
将你自定义的过滤器放在templatetags包下的一个模块里。
-
这个模块的名字是后面载入标签时使用的标签名,所以要谨慎的选择名字以防与其他应用下的自定义标签和过滤器名字冲突,当然更不能与Django内置的冲突。
为了让{% load xxx %}
标签正常工作,包含自定义标签的app必须在INSTALLED_APPS
中注册。
在templatetags包中放多少个模块没有限制。只需要记住{% load xxx %}
将会载入给定模块名中的标签/过滤器,而不是app中所有的标签和过滤器。
要在模块内自定义标签,首先,这个模块必须包含一个名为register
的变量,它是template.Library
的一个实例,所有的标签和过滤器都是在其中注册的。所以把如下的内容放在你的模块的顶部:
from django import template
register = template.Library()
编写过滤器:
自定义过滤器就是一个带有一个或两个参数的Python函数:
注意:这个Python函数的第一个参数是你要过滤的对象,第二个参数才是你自定义的参数。而且最多总共只能有两个参数,所以你只能自定义一个参数!这是过滤器的先天限制。
- 变量的值:不一定是字符串形式。
- 参数的值:可以有一个初始值,或者完全不要这个参数。
由于模板语言没有提供异常处理,任何从过滤器中抛出的异常都将会显示为服务器错误。
下面是一个定义过滤器的例子:
def cut(value, arg): """将value中的所有arg部分切除掉""" return value.replace(arg, '')
下面是这个过滤器的使用方法:
{{ somevariable|cut:"0" }}
大多数过滤器没有参数,在这种情况下,你的过滤器函数不带额外的参数即可,但基本的value参数是必带的。例如:
def lower(value): return value.lower()
注册过滤器:
一旦你写好了过滤器函数,就需要注册它,方法是调用register.filter
,比如:
register.filter('cut', cut) register.filter('lower', lower)
Library.filter()
方法需要两个参数:
- 过滤器的名称:一个字符串对象
- 编译的函数 :你刚才写的过滤器函数
还可以把register.filter()
用作装饰器,以如下的方式注册过滤器:
@register.filter(name='cut') def cut(value, arg): return value.replace(arg, '') @register.filter def lower(value): return value.lower()
上面第二个例子没有声明name参数,Django将使用函数名作为过滤器的名字。
自定义过滤器就是这么简单,使用起来也和普通的过滤器没什么区别。我们用Python的方式解决了HTML的问题。