当前位置:   article > 正文

flask--过滤器详解与自定义过滤器_flask 过滤

flask 过滤

1. 什么是过滤器

过滤器是通过|进行使用的,例如{{ name|length }},将返回name的长度,过滤器相当于是一个函数,吧当前的的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再渲染到模板页面中。

2. Jinja2模板内置的过滤器

  1. abs(value):返回一个数值的绝对值,例如{{ -1|abs }}。如果给的参数类型不为数字,就会报错。
  2. default(value,default_value,boolean=False):如果当前变量没有值,则会使用参数中的值来代替。
{{ signature|default('此人很懒,什么都没有写。') }}
  • 1

当我们的signature参数不存在时,即视图函数中没有传入参数的时候,就是使用default里面的默认值。
如果我们从视图函数中传入了signature这个值,但是它的值为'',[],None,{}这些值得时候,就不会使用default()里面的默认值了,因为我们是传入了signature这个变量的,只是值为空的而已,所以default()就不会使用我们传入的默认的值了。这个时候我们可以设置boolean=True,那么当我们传入'',[],None,{}这些值的时候,default()过滤器也回去使用我们传入的默认值了。

我们其实也可以用使用or来代替default()过滤器。

{{ signature|default('此人很懒,什么都没有写。',boolean=True) }}
# 等价于下面的or语句 
{{ signature or '此人很懒,什么都没有写' }}
  • 1
  • 2
  • 3
  1. escape:转义字符,会将<、>等符号转义为html重的符号。让html把它当成一个普通的字符窜来进行解析,而不是当成html语言来解析。
    例如当我们传入的signature参数为<script>alert("hello")</script>这样的一个字符窜的时候,我们肯定要对它进行转义,否则的话那别人能对我们的网站干的事情就很多了。
{{ signature|escape }}
  • 1

其实在flask中,默认是开启了自动转义的功能的,我们不使用escape过滤器也是可以的。

  1. safe:告诉模板我们传入的参数是安全的,就不会自动去转义里面的特殊字符,html就会去解析里面的特殊字符。也就是和escape过滤器功能相反。
{{ signature|safe }}
  • 1

这个时候如果我们的signature的值为<script>alert("hello")</script>,那么这个里面的字符窜就会被解析了。

  1. first(value): 返回序列的第一个元素
  2. last(value): 返回序列的最后一个元素
# 传入参数为
names = ['小明','小红']
# 模板中使用
{{ names|first }}
{{ names|last }}
  • 1
  • 2
  • 3
  • 4
  • 5

注意:

  • 如果是一个字典,那么返回的是key的值
  1. format(value,*args,**kwargs): 格式化字符窜,和python中写法是一样的。
{{ "%s" - "%s"|format('hello','world') }}
  • 1
  1. length(value): 返回一个序列或字典的长度
# 传入参数为
names = ['小明','小红']
persons = {'name':'小明','age':'18','height':180}

# 模板中使用
{{ names|length }}
{{ persons|length }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  1. join(value,d=’’): 将一个序列用d这个参数的值拼接成字符窜
# 传入参数为
values = [1,2,3]

# 模板中使用
{{ values|join }} # 如果没有给参数,默认是以空字符窜进行拼接
{{ values|join('-') }} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. int(value): 将值转换为int类型
  2. float(value): 将值转换为float类型
  3. string(value): 将变量转化为字符窜
  4. lower(value): 将字符窜转化为小写
  5. upper(value): 将字符窜转化为大写
  6. replace(value,old,new): 将字符窜中的old内容替换为new内容
  7. truncate(value,length=255,killwords=False,end=’…’): 截取length长度的字符窜
{{ "foo bar baz qux"|truncate(9) }}  # -> foo...
{{ "foo bar baz qux"|truncate(9,True) }} # -> foo ba...
{{ "foo bar baz qux"|truncate(9,True,'xxx') }} # -> foo baxxx
  • 1
  • 2
  • 3

结果解释:

  • 第一句代码因为我们只给了一个长度9,这个时候truncate过滤器就会先去截取(9-3)长度的字符窜,为什么是(9-3)呢,因为end='...'的长度为3,也就是会截取到'foo ba',然后因为killwords默认值False,就会截取到的字符窜以空格进行从右边开始分割一次.,然后再去第一个字符窜,这里就会得到'foo'了,然后再和end='...'进行拼接,也就会得到foo...这个结果了。
  • 第二句代码因为我们传入了killwords参数为True,那么就不会对截取的字符窜在进行以空格分割了,直接和end='...'参数进行拼接返回。
  • 第三句代码和第二句一样,只是我们改变了end参数的值而已.
  1. striptags(value): 删除字符窜中的所有的HTML标签,字符窜里面出现的多个空格也会替换为一个空格。
{{ '<h1>hello world</h1>'|striptags }} # -> hello world
  • 1
  1. trim(value): 删除字符窜前面和后面的空白字符.
  2. wordcount(value): 计算一个长字符窜中单词的个数。
import re
# 单词的匹配规则为
re.compile(r'\w+', re.UNICODE)

# \w匹配的是a-z和A-Z以及数字和下划线,
  • 1
  • 2
  • 3
  • 4
  • 5

这里只是列出了比较常用的过滤器,更多的过滤器可以查看官方文档http://jinja.pocoo.org/docs/2.10/templates/#list-of-builtin-filters

3. 自定义过滤器

在flask中,虽然拥有很多过滤器,但是可能还是满足不了我们的需求,那么我们就可以自定义过滤器。

示例:

# app.py中
@app.template_filter('my_cut')
def cut(value):
    value = value.replace('hello','')
    return value

# 模板文件中
{{ 'hello world'|my_cut }} # -> world 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面就是在flask自定义过滤器的写法,还是很简单的,我们只需要app.template_filter这个装饰器就可以了,然后里面传入我们过滤器的名字。当我们使用my_cut的时候,就会执行cut函数,然后将值传入cut函数中,所以我们的过滤器函数必须至少有一个参数。

4. 实际案例

定义一个过滤器,功能如下:

  1. 传入一个具体的时间
  2. 如果该时间间隔现在小于1分钟,就显示刚刚
  3. 如果大于一分钟,小于1小时,就显示xx分钟以前
  4. 如果大于一小时小于24小时,就现实xx小时以前
  5. 如果大于24小时小于30天,就现实xx天以前
  6. 否则就显示具体时间

app.py文件中写入代码:

from flask import Flask,render_template
from datetime import datetime

app = Flask(__name__)

@app.template_filter('handle_time')
def handle_time(time):
    '''
    time 距离现在的时间间隔
    1. 如果该时间间隔现在小于1分钟,就显示刚刚
    2. 如果大于一分钟,小于1小时,就显示xx分钟以前
    3. 如果大于一小时小于24小时,就现实xx小时以前
    4. 如果大于24小时小于30天,就现实xx天以前
    5. 否则就显示具体时间
    :param time:
    :return:
    '''
    # 如果不是传入的参数不是datetime类型的数据,就直接原样返回就行了
    if isinstance(time,datetime):
        now = datetime.now()
        # 得到时间差秒数
        timestamp = (now - time).total_seconds()
        if timestamp < 60:
            return "刚刚"
        elif timestamp >= 60 and timestamp < 60*60:
            minutes = int(timestamp // 60)
            return "{}分钟前".format(minutes)
        elif timestamp >= 60*60 and timestamp < 60*60*24:
            hours = int(timestamp // (60*60))
            return "{}小时前".format(hours)
        elif timestamp >= 60*60*24 and timestamp < 60*60*24*30:
            days = int(timestamp // (60*60*24))
            return "{}天前".format(days)
        else:
            return time.strftime("%Y-%m-%d %H:%M")
    else:
        return time

@app.route('/')
def index():
	context = {'pub_time':datetime(year=2019,month=7,day=16,hour=11,minute=10,second=0)}
	return render_template('index.html',**context)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

index.html文件中写入代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>custom filter demo</title>
</head>
<body>
	<p>发表时间: {{ pub_time|handle_time }}</p>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后我们修改pub_time的值,就能够查看到对应的效果了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/533792
推荐阅读
相关标签
  

闽ICP备14008679号