Flask模板--过滤器与测试器

1. 过滤器

1.1 过滤器简介
  • 使用场景: 一般后端服务做数据的处理并返回给前端,但可能存在多个不同的前端,且展示方式不同,此时就需要前端处理数据的展示方式(格式化、运算等)
  • 模板中不能直接调用 Python 中的某些方法,那么这就用到了过滤器函数。
  • 可以使用自带的管道过滤器,也可以自定义过滤器
1.2 管道过滤器

语法: {{variable | filter_name(*args)}}

  • 字符串
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
<p>{{ name | default('No name', true) }}</p>

{# 单词首字母大写 #}
<p>{{ 'hello' | capitalize }}</p>

{# 单词全小写 #}
<p>{{ 'XML' | lower }}</p>

{# 去除字符串前后的空白字符 #}
<p>{{ ' hello ' | trim }}</p>

{# 字符串反转,返回"olleh" #}
<p>{{ 'hello' | reverse }}</p>

{# 格式化输出,返回"Number is 2" #}
<p>{{ '%s is %d' | format("Number", 2) }}</p>

{# 关闭HTML自动转义 #}
<p>{{ '<em>name</em>' | safe }}</p>

{% autoescape false %}
{# HTML转义,即使autoescape关了也转义,可以缩写为e #}
<p>{{ '<em>name</em>' | escape }}</p>
{% endautoescape %} 

{# truncate: 字符串截断 #}          
<p>{{ 'hello every one' | truncate(9)}}</p>


{# format(value,*arags,**kwargs):格式化字符串 #}   
{{ "%s" - "%s"|format('Hello?',"Foo!") }}

{# 其他 #}   
replace(value,old,new): 替换将old替换为new的字符串。
striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
trim:截取字符串前面和后面的空白字符。
string(value):将变量转换成字符串。
wordcount(s):计算一个长字符串中单词的个数。
  • 数字
{# 四舍五入取整,返回13.0 #}
<p>{{ 12.8888 | round }}</p>

{# 向下截取到小数点后2位,返回12.88 #}
<p>{{ 12.8888 | round(2, 'floor') }}</p>

{# 绝对值,返回12 #}
<p>{{ -12 | abs }}</p> 
  • 列表
{# 取第一个元素 #}
<p>{{ [1,2,3,4,5] | first }}</p>

{# 取最后一个元素 #}
<p>{{ [1,2,3,4,5] | last }}</p>

{# 返回列表长度,可以写为count #}
<p>{{ [1,2,3,4,5] | length }}</p>

{# 列表求和 #}
<p>{{ [1,2,3,4,5] | sum }}</p>

{# 列表排序,默认为升序 #}
<p>{{ [3,2,1,5,4] | sort }}</p>

{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
<p>{{ [1,2,3,4,5] | join(' | ') }}</p>

{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
<p>{{ ['tom','bob','ada'] | upper }}</p> 
  • 字典
<body>
    <!-- 定义变量列表 -->
    {% set users=[{'name':'Tom','gender':'M','age':20},
    {'name':'John','gender':'M','age':18},
    {'name':'Mary','gender':'F','age':24},
    {'name':'Bob','gender':'M','age':31},
    {'name':'Lisa','gender':'F','age':19}] %}

    <h1>按照age倒序排列</h1>
    <div>
        {% for user in  users | sort(attribute='age', reverse=true) %}
        <li>{{ user.name }}, {{ user.age }}</li>
        {% endfor %}
    </div>
    <h1>按照gender分组</h1>
    <div>
        {% for user in users|groupby('gender') %}
        <!-- <li>{{ user }}<ul> -->
        <li>{{ user.grouper }}<ul>
            {% for u in user.list %}
            <li>{{ u.name }}</li>
            {% endfor %}</ul></li>
        {% endfor %} 
    </div>
    <h1>获取name值,拼接展示</h1>
    <div>
        <p>{{ users | map(attribute='name') | join(', ') }}</p> 
    </div>
</body>

在这里插入图片描述

  • tojson
@app.route('/')
def index():
    return render_template('demo.html', user={'name':'zhangsan', 'age':18})
   <script type="text/javascript">
       var user = {{ user | tojson  }}
       console.log(user.name)  // zhangsan
   </script>
1.3 语句块过滤器
<body>
    {% filter upper %}
        This is test content!
    {% endfilter %}
</body>

在这里插入图片描述

1.4 自定义过滤器
  • 方式一:@app.template_filter(filter_name)
@app.route('/')
def index():
    return render_template('demo.html', title='## Hello,World')


@app.template_filter('md')
def md_to_html(txt):
    return markdown(txt)
<body>
    <p>{{ title }}</p>
    <p>{{ title|md }}</p>
    <p>{{ title|md|safe }}</p>
</body>
  • 方式二:app.add_template_filter(func, filter_name)
@app.route('/')
def index():
    return render_template('demo.html',title='## Hello,World')


def md_to_html(txt):
    return markdown(txt)

app.add_template_filter(md_to_html, 'md')

在这里插入图片描述

  • 源码

从源码可以看出,实际是app.jinja_env.filters['name'] = f

    @setupmethod
    def add_template_filter(self, f, name=None):
        """Register a custom template filter.  Works exactly like the
        :meth:`template_filter` decorator.

        :param name: the optional name of the filter, otherwise the
                     function name will be used.
        """
        self.jinja_env.filters[name or f.__name__] = f

2. 测试器

2.1 测试器简介
  • 和过滤器非常相似,区别是测试器总是返回布尔值
  • 一般与if一起使用
2.2 内置测试器
{# 检查变量是否被定义,也可以用undefined检查是否未被定义 #}
{% if name is defined %}
    <p>Name is: {{ name }}</p>
{% endif %}

{# 检查是否所有字符都是大写 #}
{% if name is upper %}
  <h2>"{{ name }}" are all upper case.</h2>
{% endif %}

{# 检查变量是否为空 #}
{% if name is none %}
  <h2>Variable is none</h2>
{% endif %}

{# 检查变量是否为字符串,也可以用number检查是否为数值 #}
{% if name is string %}
  <h2>{{ name }} is a string.</h2>
{% endif %}


{# 检查变量是否可被迭代循环,也可以用sequence检查是否是序列 #}
{% if [1,2,3] is iterable %}
  <h2>Variable is iterable.</h2>
{% endif %}

{# 检查变量是否是字典 #}
{% if {'name':'test'} is mapping %}
  <h2>Variable is dict.</h2>
{% endif %}
2.3 自定义测试器
  • 方法一: app.add_template_test(func, filter_name)
def func():
    pass

app.add_template_test(func, 'func1')
  • 方法二: @app.template_test(ffilter_name)
@app.template_test('func1')
def func():
    pass
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值