在上一篇中,我们学习了关于前端框架与使用模板的一些知识,知道如何在模板中调用传入的参数以及如何继承模板以减少重复的代码,但是仅仅这些还是不太够的,有时候我们还需要对传入的参数进行一些判断与操作,所以这一篇我们来深入了解一下flask在渲染模板时的一些其他操作


一、模板接受的数据类型

在python中数据有各种各样的类型,比如字符串、整数等等,而在模板中也是可以接受不同类型的数据,jinja2支持python的所有数据类型,包括字符串、整数、浮点数、列表、字典、对象等,在模板中的使用方法也和在python中无异。


二、过滤传入的数据

上一篇我们在模板中使用{{ user }}这样的语句,用变量名来调用传入的参数,但有时候我们需要对变量进行一些处理,比如将结构性带html标签的文章传入模板中,如果不进行处理就会出现文章无法正常显示,所以对于变量进行过滤就显得非常重要啦

jinja默认对传入的变量进行转义,即传入html语句或js语句,在渲染出的页面里的是无法执行的,而是显示为普通的字符。

要想变量正常显示我们就需要用到过滤器,jinja2提供许多的过滤器,这里展示几个常用的过滤器(更多过滤器请访问jinja2文档的List of Builtin Filters查看)

过滤器 作用
safe() 不对内容进行转义
striptags() 去除内容所有的html标签
trim() 去除内容首尾空行

过滤器的用法为{{ user|safe }}

让我们来测试一下吧

frog.py

@app.route('/filter')
def test_filter():
    return render_template('filter.html',words='<h1>hello filter!</h1>')

templates/filter.html

{% extends 'base.html' %}

{% block title %}filter{% endblock %}

{% block content %}
转义:         {{ words }}<br/><br/>
不转义:       {{ words|safe }}<br/><br/>
去除html标签: {{ words|striptags }}
{% endblock %}


三、数据的判断与渲染

有时候我们需要对传入模板的数据进行判断,满足某种条件才会渲染出某些部分,否则渲染另一种部分,让我们来看看如何实现吧!

frog.py

@app.route('/age/<int:myage>')
def age(myage):
    return render_template('age.html',myage=myage)

templates/age.html

{% extends 'base.html' %}

{% block title %}你多大了?{% endblock %}

{% block content %}

{% if myage<=12 %}
<h1>你是一名少年</h1>
{% elif myage <18 %}
<h1>你是一名青少年</h1>
{% else %}
<h1>你是一名成年人</h1>
{% endif %}

{% endblock %}

我们来测试一下

在模板中我们用{%%}包裹着判断语句,一旦满足条件就渲染判断语句下的部分,判断部分由{% if ... %}开头,{% endif %}结尾。


四、遍历数据

既然jinja2支持传入列表、字典之类的数据类型,那在模板中也应当支持循环遍历数据的,写法也是用{%%}包裹,让我们来看看吧!

frog.py

@app.route('/for')
def for_return():
    fruits=['apple','orange','watermelon']
    profile1={'id':1,'name':'Felix','sex':'male','height':'178cm','weight':'74kg'}
    profile2={'id':2,'name':'Lily','sex':'female','height':'169cm','weight':'50kg'}
    profiles=[profile1,profile2]
    return render_template('for.html',fruits=fruits,profiles=profiles)

templates/for.html

{% extends 'base.html' %}

{% block title %}遍历数据{% endblock %}

{% block content %}

<h2>我喜欢的水果</h2>
<ul>
    {% for fruit in fruits %}
    <li>{{ fruit }}</li>
    {% endfor %}
</ul>


<h2>个人信息表</h2>
<table class='mdui-table'>
    <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>sex</th>
            <th>height</th>
            <th>weight</th>
        </tr>
    </thead>
    <tbody>
        {% for profile in profiles %}
        <tr>
            <td>{{ profile['id'] }}</td>
            <td>{{ profile['name'] }}</td>
            <td>{{ profile['sex'] }}</td>
            <td>{{ profile['height'] }}</td>
            <td>{{ profile['weight'] }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

{% endblock %}

然后我们测试一下

在模板中我们使用{% for item in items %}......{{ item }}......{% endfor %},这样的形式来循环迭代数据


五、模板中的函数(宏)

有时候我们需要为某些对象数据生成一种特定的结构样式,但经常会出现需要渲染许多结构相同只是部分数据不同的组件,这时宏就非常有必要了,宏类似于函数,我们输入一些参数,便渲染出带有参数数据的一种特定结构样式,我们来试试看吧!

frog.py

@app.route('/tags')
def tags():
    return render_template('tags.html')

templates/tags.html

{% extends 'base.html' %}

{% block title %}标签{% endblock %}

{% block content %}

{% macro tag(words) %}
<div class='mdui-chip'>
    <span class='mdui-chip-title'>{{ words }}</span>
    <span class='mdui-chip-delete'><i class='mdui-icon material-icons'>cancel</i></span>
</div>
{% endmacro %}

<h1>标签</h1>
{{ tag('好吃') }}
{{ tag('懒做') }}
{{ tag('屎尿多') }}

{% endblock %}

看一下效果

我们使用{% macro mcname(parm) %} ...... {{ parm }} ......{% endmacro %}来定义一个宏,在需要用到宏的地方使用{{ mcname(parm) }}来调用宏

有时候可能需要在多个模板中用到同一个宏,这时候我们就可以把宏单独保存到一个模板中,在需要用到的模板中引入宏的模板即可,像这样

templates/macros.html

{% macro tag(words) %}
<div class='mdui-chip'>
    <span class='mdui-chip-title'>{{ words }}</span>
    <span class='mdui-chip-delete'><i class='mdui-icon material-icons'>cancel</i></span>
</div>
{% endmacro %}

templates/tags.html

...
{% import 'macros.html' as macros %}

{{ macros.tag('好吃') }}
...

以上就是关于模板渲染的一些操作啦,其实这一部分还是比较有意思的,就像在画画一样,学到这里已经可以做出许多有意思的东西了,接下来我们还将继续关于模板的学习,那我们下一篇再见吧!

当前Frog项目仓库地址:http://codemole.cn/felix/Frog/src/frog3.2

评论

Felix 管理员

按照这个速度我可能要写到明年。。。

回复

  • 最新随笔

  • 尝试让DALLE生成一些连续的精灵图,让gpt帮忙生成一些提示词,如果能稳定输出的话就很强大了。
    让gpt帮忙生成的DALLE提示词
    "Generate a pixel art sprite sheet of a character walking in four directions (north, south, east, west) in a retro video game style."
    "Create a series of pixel art frames showing a character performing different actions like walking, running, jumping, and attacking in a classic 2D game aesthetic."
  • 路过别人山庄的门口,被一条大黑狗边叫边追过来,幸好骑电动车,不然还不一定跑得过,哈哈哈哈哈哈哈哈哈哈。
  • 最近两周也没咋出去玩,主要也是觉得没啥好玩的(笑哭)。看完布莱恩阿瑟的《复杂经济学》后,里面那个酒吧问题勾起我的兴趣,最近空了就花了些时间实现个python版本,顺便搞了篇博文,很享受这种新知识能和已有知识碰撞的感觉。(配张前段时间拍的图片,梧桐山门口前面那条路,挺漂亮的)
  • 盐田港夜景
  • 为啥这猫总喜欢喝杯子里的水
  • 确实开始冷了,在树林里至少要比人类聚集区低个几度,进出入口就能很明显感觉到。看看深圳水库的风景,貌似后面的视野更开阔。
  • 给随笔加了多图的功能,传一传周末拍的风景图,漫无目的的逛也挺好玩的。
  • 逻辑自洽是一套体系的根基,最根本的因素,最吸引人的地方