有故事,带项目的flask教程(4)---flask的jinja2模板---模板的if,for高级用法,过滤器和模板继承(2)

新的一天,老项和小王还是早早来到了公司,继续开始flask的教和学。

老项说:“今天上班前这些时间我正好把模板剩下的一些内容给你讲一下,主要就是jinja2模板的过滤器和继承,讲完这些你今天回去就可以开始准备这个项目的前端页面了。然后把页面作为模板对数据部分的展示用jinja2模板引擎进行改造。昨天的任务完成的怎么样?有没有遇到什么问题?”

小王说:“老铁你别说,还真有问题,你看看我总结的笔记,昨天遇到了三个问题,弄得我夜不能寐,要不您帮我看看。”

         老项看了看小王的笔记,主要有以下三个问题。

  1. 小王在做任务的时候把车系信息都放在了一个字典里面,想让前端通过渲染字典的key能够找到对应的值,但试了很多方法都不成功。
  2. 小王在使用循环模板的时候,想实现一个功能,默认不显示第一个元素的内容,实际就是想取得循环时的下标,但也没做出来
  3. 小王在使用if判断模板的时候,想测试变量是否是字符串,也不知道怎么做

老项看完以后说:“你的问题我知道了,你这些问题对于jinja2来说,都是小菜一碟,我们先解决你的问题,再讲新的内容吧。”老项说完,就开始了讲解

 

         更复杂数据的渲染

小王第一个问题自己写的代码如下图。

后台代码中,小王定义了一个有多个键值对的字典,然后在前台模板中想直接使用字典的键来获取键对应的值。不过后台的render_template方法如何传参,小王就没有太好的办法了,如果一个键值对作为一个参数,后面要写的参数就太多了,而且不够灵活。解决方案其实很简单,用以前python基础中**kwargs的方式即可。代码如下图。

关键代码在第16行,在参数前面加个**,把字典转换成关键字参数即可。具体运行的效果大家可以自行测试。

将第一个问题给小王解决以后,老项有开始讲第二个问题了。

 

在前端模板获取for循环的更多信息

小王的第二个问题实际就是想在前端模板获取循环的次数等更多信息。jinja2当然也帮我们考虑到了这一点,在循环时,jinja2给我们提供了一个叫loop的对象,通过这个对象我们可以获取更多有关循环的信息。关于loop的属性,可以看一下我们总结的下面这个表。

属性名称

意义

loop.index

从1开始计数的当前循环迭代次数

loop.index0

从0开始计数的当前循环迭代次数

loop.revindex

到循环为止需要迭代的次数

loop.first

是否第一次循环

loop.last

是否最后一次循环

loop.length

序列中元素的数量

根据上表结合小王的需求,使用loop.first即可,前后台的代码如下图。

“怎么样,小王,用起来还是很简单吧?给你布置个小任务,今天回去以后把loop其它的属性使用测试一下。”老项给小王布置了个临时任务,又继续了第三个问题的讲解。

使用if做更多的测试

在jinja2模板中,我们可以使用if和python关键字is结合,再配合内置的一些测试方法和测试器,可以做更多的测试判断。小王的需求是测试传递过来的数据是不是字符串,用string测试器即可。具体的前后端代码及运行截图如下。

 

 

代码的12行使用了string测试器。除了string测试器,jinja2还提供了更多的测试器和测试方法,请见下表。

测试器

测试器意义

defined/none

检查一个对象是否被定义 等价于{% if value %}

upper/lower

检查是否都是大写或者小写

string

检查是否字符串

odd/even

检查一个整数是否奇数还是偶数

iterable

检查一个对象是否可以迭代

mapping

检查一个对象是否是键值对的形式,比如字典的形式

除了这些测试器外,还有一些带参数的测试方法,见下表。

测试方法

测试方法意义

callable(object)

测试一个对象是否可调用

defined/undefined(object)

测试一个对象是否被定义

divisibleby(value,num)

测试value是否可以被num整除

escaped(value)

测试对象是否被转码

iterable(value)

测试对象是否可迭代

lower/upper(value)

测试value是否都是大写或小写

none(value)

测试value是否为none

number(value)

测试value是否是数字

sameas(value,other)

测试两个对象是否为同一个对象

等老项把测试器和测试方法展示给小王以后,小王问:“如果上面的测试方法都满足不了我的需求,那有没有办法可以自定义测试方法呢?比如我想测试车系名称是否超过两个字符。”

“这个flask其实也可以做,我马上把代码敲出来给你看看。”老项说完,手速飞快的敲起了代码。自定义测试器的前后台代码如下。

 

在后台代码中,我们先写了一个普通的方法(第六行)。这个方法传入一个字符串,该字符串长度大于2则返回True。然后在代码的第10行将该方法作为自定义的测试方法加入到jinja2的测试方法中,顺便命名为car_name_test。

前台的代码直接使用该测试器(第11行),测试长度大于2的车系名称。最终的输出结果见下图。

“小王,关于测试方法我给你布置个任务吧,后台传给前端一个列表,请在页面上显示该列表下标为偶数的元素,用测试方法做。好了,接下来,我们说一下模板的过滤器吧。”解决完小王的三个问题,老项开始讲解模板的过滤器。

 

jinja2模板过滤器

当我们在页面展示数据的时候,有时需要对数据做进一步的处理,比如把大写字符转换成小写。这个时候就可以使用模板的过滤器了。假设有这样一个需求,需要直接在前端页面显示后台序列数据的最后一个元素,用过滤器的方式,前端代码和运行结果如下。(后台代码同上一个例子的后台)

         前端代码的第10行使用了过滤器,过滤器的使用有些类似于linux的管道操作,就是用一个‘|’符号连接后面的过滤器。除了针对迭代对象的last过滤器,还有更多的过滤器,常用的一些过滤器请见下表。

过滤器名称

过滤器说明

safe(value)

过滤的内容渲染时不转义

capitalize(value)

把值的首字母转换成大写,其他字母转换成小写

lower(value)/ upper(value)

把value转换成小/大写形式

replace(value,old,new)

将value中old子串替换成new

title(value)

把value中每个单词的首字母都转换成大写

trim(value)

把value的首尾空格去掉

striptags(value)

渲染前把value中所有的HTML标签都删除

first(value)/last(value)/random(value)

获取可迭代对象value的第一个/最后一个/随机一个元素

length(value)

获取可迭代对象value的长度

join(value,d=u”)

将一个序列value用d的值拼接成字符串

int(value)/ float(value)/ string(value)

把value转换成int/float/string

truncate(value,length=255,killwords=False)

截取length长度的字符串

wordcount(value)

获取一个长字符串中单词的个数

注意在使用过滤器的时候,表中的value就是管道“|”左边的值,所以实际并不传入value。我们再来一个带参数的例子,代码见下图。

上面的代码在列表最后一个元素的基础上,将‘迪’替换成了‘ 车’。从第10行代码可以看出,可以链式的使用过滤器,如果是有参数的过滤器,则像函数调用那样处理。

“老项,还是那个问题,我能自定义过滤器吗?”老项刚讲完,小王就问。

“对的,jinja2可以使用自定义的过滤器,自定义过滤器一个函数,这个函数至少有一个参数作为被过滤的内容,即管道符号“|”左边的变量,其他的参数根据需要传入。我们还是直接看代码吧。”老项回答道,代码如下。

 

从第一个图片后台代码可以看到,我们首先定义了一个函数(第六行到第十行),该函数用于截取特定的值,函数传入两个参数,第一个参数就是要进行过滤的值,也就是管道左边的变量,第二个参数是指定从哪个位置开始截取第一个参数,返回截取后的结果。定义好过滤器函数以后,我们需求对过滤器函数进行注册,见第13行到第15行代码。注册的名称就是filters这个字典的key,即“cut_str”。注册成功后,就可以在前端代码中使用该过滤器了。

把上面的内容讲完以后,老项说:“好了,过滤器就先讲这么多,回去记得把常用的过滤器都测试一下。然后自己写一个过滤器,这个过滤器可以获取可迭代对象的长度。最后,我们来说一下flask模板的继承。”

 

flask模板的继承

通过jinja2引擎也可以实现模板的继承。通过继承我们可以把页面中的公共部分提取出来,放在一个父模板里面,避免写重复的前端代码,从而更有利于前端代码的修改和管理。flask是通过{% extern %}和{% block %}来实现模板的继承的。我们先写一个父模板base.html。代码如下。

这个base.html包含了一个前端代码的基本构成,对于可变的部分,用了两个block进行处理(代码第5行和第8行)。如果需要继承这个base.html文件,使用{% extern %}即可,我们再构建一个html文件,代码如下图。

这个车系列表页重载了base里面的两个block,增加了显示的页面标题和具体内容,注意block要进行闭合。后台的代码需要调整一下,渲染的页面应该换成“car_list.html”,代码和页面效果如下图。

“好了,这也快上班了,今天就讲这么多吧。今天你就可以回去设计你的页面了,然后按照jinja2引擎来填充你页面的数据,并对页面通过继承关系进行处理。”老项讲的也比较累了,眼看也要上班了,就结束了今天的讲解。

“遵命,老铁”小王答应道,就回自己的工作岗位了。

 

本章任务:

  1. 完成教程里面的案例和老项布置的任务。
  2. 会写前端页面的同学可以把本项目的几个前端页面写一写,然后对数据进行处理,对页面模板进行继承处理。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值