为什么要自定义过滤器?
Django中虽然已经内置了很多过滤器,但是并不能满足我们的日常开发,所以我们需要自定义过滤器。
首先我们先搭建好一个测试环境。
在一个新建的项目中创建一个article
的app,然后在article
中新建一个urls.py
的文件,然后在templates
中新建一个index.html
的文件,(如果没有templates这个文件夹需要手动创建),然后进行配置,使article
中的views对index.html
进行渲染。直至配置好测试环境。
在一切配置好了之后,然后在article
中新建一个名为templatetags
的package
。
注意: 必须是一个包,并且包的名字也必须为templatetags
package和文件夹的区别:package
中会有一个__init__.py
的文件。只用拥有__init__.py
的package
才能被导入。
建包方法:article
文件夹上右键=>new=>Python Package.然后名字为templatetags
然后在templatetags
中新建一个python文件,文件名就可以随便取了,我这里就新建了一个my_filter.py
的文件。
在里面写入我们自定义的过滤器的规则:
from django import template
register = template.Library()
#过滤器函数主体,第一个参数是过滤器前面的值, 第二个参数是过滤器后面的值
#可以不用有第二个参数,但是必须要有第一个参数,参数最多两个
def greet(value,word):
return value + word
#注册自定义的过滤器
# 过滤器的名字 过滤器的主体函数
register.filter('greet',greet)
这里我么就自定义好了一个过滤器,它的功能是将字符窜进行拼接。
然后在views中写入代码
from django.shortcuts import render
# Create your views here.
def index(request):
context = {'value':'张三'}
return render(request,'index.html',context=context)
然后配置url,然后在index.html
编写代码:
首先,要想我们自定义的过滤器被执行,我们必须先将包含过滤器的app
进行注册。即将这里的article
添加到settings.INSTALLED_APS
中,不然Django也找不到这个过滤器。
其次,在渲染的html
文件中的代码最上面加载自定义的过滤器:
{% load my_filter %}
这里的my_filter
是我定义过滤器的文件名。
这样,在html
中才能使用我们自定义的过滤器。
然后在index.html
中的body中写入代码:
{{ value|greet:'world' }}
接下来就自行输入网址,和改变参数进行测试。
这样,我们的过滤器就从定义到使用的完全弄好了。
总结(创建过滤器的基本步骤):
- 首先在某个app中,创建一个python包,叫做
templatetags
,注意,这个包的名字必须为templatetags
,不然就找不到。 - 在这个
templatetags
包下面,创建一个python文件用来存储过滤器。 - 在新建的python文件中,定义过滤器(也就是函数),这个函数的第一个参数永远是被过滤的那个值,并且如果在使用过滤器的时候传递参数,那么还可以定义另外一个参数。但是过滤器最多只能有2个参数。
- 在写完过滤器(函数)后,要使用
django.template.Library.filter
进行注册。 - 还要把这个过滤器所在的这个app添加到
settings.INSTALLED_APS
中,不然Django也找不到这个过滤器。 - 在模板中使用
load
标签加载过滤器所在的python包。 - 然后就是使用自定义的过滤器了。
django.template.Library.filter
还可以当作装饰器来使用。如果filter
函数没有传递任何参数,那么将会使用这个函数的名字来作为过滤器的名字。当然如果你不想使用函数的名字来作为过滤器的名字,也可以传递一个name
参数。
实战案例 :自定义时间计算过滤器
有时候经常在朋友圈,微博中可以看到一条信息发表的时间,并不是具体的时间,而是距离现在多久,比如:刚刚
,1分钟前
等,DTL内置的过滤器是没有这个功能的。因此我们需要自定义一个这样的过滤器。
首先我们先打开my_filter.py
这个文件。
修改代码为:
from django import template
register = template.Library()
#过滤器函数主体,第一个参数是过滤器前面的值, 第二个参数是过滤器后面的值
#可以不用有第二个参数,但是必须要有第一个参数,参数最多两个
@register.filter('greet') #和下面的register.filter('greet',greet)功能是一样的
#1.可以不用传参数,即默认使用下面的函数名作为过滤器的名字
#2.也可以传入一个参数,即自定义过滤器的名字。
#3.最多只能传一个参数。
def greet(value,word):
return value + word
#注册自定义的过滤器
# 过滤器的名字 过滤器的主体函数
register.filter('greet',greet)
然后我们使用了另外一种方法来注册我们的过滤器。这样我们就可以把下面的register.filter('greet',greet)
删掉了也能实现效果。
接下来我们在my_filter.py
中自定义我们的时间过滤器
from django import template
from datetime import datetime
register = template.Library()
@register.filter
def time_since(value):
'''
time距离现在时间的间隔
1.如果时间间隔小于一分钟以前,那么就显示刚刚。
2.如果是大于一分钟小于一小时,那么就显示xx分钟前
3.如果是大于一小时小于24小时,那么就是显示xx小时以前
4.如果是大于24 小时小于30天以内,那么就显示xx天以前
5.否则就显示具体的时间 2017-10-04 12:45
'''
if not isinstance(value,datetime):
return value
now = datetime.now()
#time.total_seconds()将时间转化为秒数
timestamp = (now - value).total_seconds()
if timestamp < 60:
return '刚刚'
elif timestamp > 60 and timestamp < 60*60:
minutes = int(timestamp/60)
return '%s分钟前' % minutes
elif timestamp > 60*60 and timestamp < 60*60*24:
hours = int(timestamp/60/60)
return '%s小时前' % hours
elif timestamp > 60*60*24 and timestamp < 60*60*24*30:
days = int(timestamp/60/60/24)
return '%s天前' % days
else:
return value.strftime("%Y-%m-%d %e:%M")
在views中传递一个参数:
from django.shortcuts import render
from datetime import datetime
# Create your views here.
def index(request):
context = {'value':'张三','time':datetime(year=2018,month=8,day=20,hour=19,minute=8,second=0)}
return render(request,'index.html',context=context)
然后在index.html
中使用time_since
过滤器
首先在文件最上面添加一行代码加载我们的过滤器。
{% load my_filter %}
然后在body中写入
{{ time|time_since }}
然后就可以查看效果了,如果需要改变时间,只需要去views中修改time
的值就行了。
==注意:==如果测试不成功,请仔细按照上面的总结来检查哪一步出错了。