Django自定义过滤器

为什么要自定义过滤器?

Django中虽然已经内置了很多过滤器,但是并不能满足我们的日常开发,所以我们需要自定义过滤器。

首先我们先搭建好一个测试环境。
在一个新建的项目中创建一个article的app,然后在article中新建一个urls.py的文件,然后在templates中新建一个index.html的文件,(如果没有templates这个文件夹需要手动创建),然后进行配置,使article中的views对index.html进行渲染。直至配置好测试环境。

在一切配置好了之后,然后在article中新建一个名为templatetagspackage
注意: 必须是一个包,并且包的名字也必须为templatetags
package和文件夹的区别package中会有一个__init__.py的文件。只用拥有__init__.pypackage才能被导入。
建包方法: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' }}

接下来就自行输入网址,和改变参数进行测试。
这样,我们的过滤器就从定义到使用的完全弄好了。

总结(创建过滤器的基本步骤):

  1. 首先在某个app中,创建一个python包,叫做templatetags,注意,这个包的名字必须为templatetags,不然就找不到。
  2. 在这个templatetags包下面,创建一个python文件用来存储过滤器。
  3. 在新建的python文件中,定义过滤器(也就是函数),这个函数的第一个参数永远是被过滤的那个值,并且如果在使用过滤器的时候传递参数,那么还可以定义另外一个参数。但是过滤器最多只能有2个参数。
  4. 在写完过滤器(函数)后,要使用django.template.Library.filter进行注册。
  5. 还要把这个过滤器所在的这个app添加到settings.INSTALLED_APS中,不然Django也找不到这个过滤器。
  6. 在模板中使用load标签加载过滤器所在的python包。
  7. 然后就是使用自定义的过滤器了。
  8. 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的值就行了。

==注意:==如果测试不成功,请仔细按照上面的总结来检查哪一步出错了。

猜你喜欢

转载自blog.csdn.net/xujin0/article/details/83388664