jinja2模板

jinja2模板

​ 视图函数的主要作用是,处理业务逻辑,返回响应内容

​ flask是使用jinja2这个模板引擎来渲染模板

使用模板的好处

  • 视图函数只负责业务逻辑和数据处理
  • 模板取到视图函数的数据结果进行展示
  • 代码结构清晰,耦合度低

1、jinja2模板介绍

模板传参

  1. 再使用render_template渲染模板的时候,可以传递关键字参数,以后直接在模板中使用即可
  2. 如果参数过多,可以将所有的参数放到一个字典或列表中。将字典打散成关键字参数可以在参数前面加**
from flask import Flask,render_template

app = Flask(__name__)

student = {
    'name': 'zhangsan',
    'age':8,
    'gender':'男'
}
student_list = [
    {'name': 'zhangsan','age':18,'gender':'男'},
    {'name': 'lisi','age':68,'gender':'女'},
    {'name': 'wangwu','age':16,'gender':'男'}
]

student_dict = {
    'a':{'name': 'zhangsan','age':18,'gender':'男'},
    'b':{'name': 'lisi','age':28,'gender':'女'},
    'c':{'name': 'wangwu','age':19,'gender':'男'}
}
@app.route('/test1')
def test1():
    return render_template('01.html', **student) # 为了方便在模板中使用,可以把字典打散

@app.route('/test2')
def test2():
    return render_template('02.html', stu_list = student_list)

@app.route('/test3')
def test3():
    return render_template('03.html', stu_dict = student_dict)

if __name__ == '__main__':
    app.run()

01.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第一个模板</title>
</head>
<body>
    学生姓名:{{ name }}
    学生年龄:{% if age >= 18 %}
                    已经成年
            {% else %}
                    未成年
            {% endif %}
    学生性别:{{ gender }}
</body>
</html>

结果

01

02.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第二个模板</title>
</head>
<body>
   {{ stu_list }}

    <table border="1px">
        <tr>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
        </tr>

        {% for stu in stu_list %}
            <tr>
                <td>{{ loop.index }}</td>
                <td>{{ stu.name }}</td> <!-- 由于stu是字典,有三种写法得到key的value-->
                {% if stu.age >= 60 %}
                    <td>已退休</td>
                {% elif stu.age >= 18 %}
                    <td>已成年</td>
                {% else %}
                    <td>未成年</td>
                {% endif %}
{#                <td>{{ stu.get('age') }}</td>#}
                <td>{{ stu['gender'] }}</td>
            </tr>
        {% endfor %}
        
    </table>
</body>
</html>

结果

02

03.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第三个模板</title>
</head>
<body>
   {{ stu_dict }}

    <table border="1px">
        <tr>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
        </tr>

        {% for stu_key,stu in stu_dict.items() %}
            <tr>
                <td>{{ loop.index }},key:{{ stu_key }}</td>
                <td>{{ stu.name }}</td> <!-- 由于stu是字典,有三种写法得到key的value-->
                {% if stu.age >= 60 %}
                    <td>已退休</td>
                {% elif stu.age >= 18 %}
                    <td>已成年</td>
                {% else %}
                    <td>未成年</td>
                {% endif %}
{#                <td>{{ stu.get('age') }}</td>#}
                <td>{{ stu['gender'] }}</td>
            </tr>
        {% endfor %}
        
    </table>
</body>
</html>

结果

03

语法

  1. 控制结构(逻辑代码){%%}
  2. 变量取值{{}}
  3. 注释{##}

2、表达式

  • 最常用的是变量,由Flask渲染模板时传过来,比如name
  • 也可以是任意一种Python基础类型,比如字符串{{stu}};或者数值,列表,元祖,字典,布尔值。
  • 运算。包括算数运算,如{{ 2 + 3 }};比较运算,如{{ 2 > 1 }};逻辑运算,如{{ False and True }}
  • 过滤器|和测试器is
  • 函数调用,如{{ current_time() }};
  • 数组下标操作,如{{ arr[1] }}
  • in操作符,如{{ 1 in [1,2,3] }}
  • 字符串连接符~,作用同Python中的 “+” 一样,如{{ "Hello " ~ name ~ “!” }}
  • None值处理{{name or “”}

3、过滤器

过滤器实质上是一个转换函数。变量可以通过过滤器进行修改,过滤器可以理解为是jinja2里面的内置函数和字符串处理函数

常用的过滤器

过滤器名称描述
safe渲染时值不转义
capitalize把值的首字母转换成大写,其他字母转换成小写
lower把值转换成小写形式
upper把值转换成大写形式
title把值中每个单词的首字母都转换成大写
trim把值的首尾空格去掉
striptags渲染之前把值中所有的HTML标签都删掉
join拼接多个值为字符串
replace替换字符串的值
round默认对数字进行四舍五入,也可以用参数进行控制
int把值转换成整型

过滤器.py

from flask import Flask,render_template

app = Flask(__name__)

student = {
    'name': 'zhangsan',
    'age':8,
    'gender':'男'
}

@app.route('/str')
def test1():
    return render_template('04字符串的过滤器.html')

@app.route('/number')
def test2():
    return render_template('05数字的过滤器.html')

@app.route('/list')
def test3():
    return render_template('06列表的过滤器.html')

@app.route('/dict')
def test4():
    return render_template('07字典的过滤器.html')

@app.template_filter('get_top3')
def get_top3(lst):# 取列表的前3个元素
    return lst[:3]

def get_qu(lst):# 计算列表中每个元素的平方,
    return list(map(lambda x:x**2,lst))
app.jinja_env.filters['get_qu'] = get_qu

@app.route('/my_filter')
def test5():
    return render_template('08自定义的过滤器.html')
if __name__ == '__main__':
    app.run()

字符串过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>字符串的过滤器</title>
</head>
<body>
    {# 当变量数据没有传入,可以给变量设置默认值 #}
    <p>{{ name | default('这个人很懒,什么都没有留下!!!') }}</p><br>
    {# 字符串的大小写转换 #}
    <p>{{ 'XYZ' | lower }}</p><br>
    {# 反转 #}
    <p>{{ 'hello world' | reverse }}</p><br>
    {# 格式化 #}
    <p>{{ '今天是%d号,天气%s' | format(17,'下雨')}}</p><br>
    {# 关闭html的自动转义 #}
    <p>{{ '<em>name</em>' | safe }}</p>
</body>
</html>

结果

04

数字过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数字的过滤器</title>
</head>
<body>
   {# 四舍五入的转换,默认取整数部分 #}
    <p>{{ 3.1415926 | round }}</p><br>
   {# 小数点后面截取n位 #}
    <p>{{ 3.1415 | round(3) }}</p><br>
   {# 取绝对值 #}
    <p>{{ -100 | abs }}</p><br>
   {#  #}
{#    <p>{{  }}</p><br>#}
{#    <p>{{  }}</p><br>#}
{#    <p>{{  }}</p><br>#}
</body>
</html>

结果

05

列表的过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>列表的过滤器</title>
</head>
<body>
{# 定义一个nums变量 #}
{% set nums = [1,5,2,6,8,3] %}
   {# 取第一个值 #}
    <p>{{ nums | first }}</p><br>
   {# 列表长度 #}
    <p>{{ nums | length }}</p><br>
   {# 求和 #}
    <p>{{ nums | sum }}</p><br>
   {# 排序 #}
    <p>{{ nums | sort }}</p><br>
    {# 变成字符串 #}
    <p>{{ nums | join(' - ') }}</p><br>
{#    <p>{{  }}</p><br>#}
</body>
</html>

结果

06

字典过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>字典的过滤器</title>
</head>
<body>
{# 定义一个字典 #}
{% set students = [
    {'name':'zs','age':38,'gender':'女'},
    {'name':'ls','age':68,'gender':'男'},
    {'name':'ww','age':8,'gender':'女'}
] %}
   {# 根据指定字段排序 #}
    <ul>
        {% for stu in students | sort(attribute='age',reverse=False) %}
            <li>{{ stu.name }},{{ stu.age }}</li>
        {% endfor %}

    </ul>

    {# 上面的数据分组,每组变成一个子列表 #}
    <ul>
        {% for group in students |groupby('gender') %}
            <li>{{ group.grouper }}</li>
            {% for stu in group.list  %}
                <li>{{ stu.name }},{{ stu.gender }}</li>
            {% endfor %}
        {% endfor %}
    </ul>
    {# 取出字典中的某一列,组成一个大的列表,然后再把列表变成字符串 #}
    <p>{{ students | map(attribute='name') | join('-') }}</p><br>
{#    <p>{{  }}</p><br>#}
</body>
</html>

结果

07

自定义的过滤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定义的过滤器</title>
</head>
<body>

    <p>{{ [1,2,3,4,5,6,7] | get_top3 }}</p><br>

    <p>{{ [1,2,3,4,5,6] | get_qu }}</p>
</body>
</html>

结果

08

4、测试器

测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,使用"is"关键字来测试

测试器本质上也是一个函数,它的第一个参数就是待测试的变量,在模板中可以省略,如果有第二个参数,模板中就必须传进去。测试器函数返回的必须是一个布尔值,这样才可以用来给if语句做判断

测试器官网文档
测试器.py

from flask import Flask,render_template
import  re
app = Flask(__name__)


@app.route('/test_demo1')
def test1():
    return render_template('09测试器.html')

# 自定义测试器,创建函数,注册
@app.template_test('isphone')
def test_phone(phone): # 测试手机号是否合法
    phone_re = r'1[3-9]\d{9}'
    return re.match(phone_re,phone)

def start_with(s,suffix):
    return s.lower().startswith(suffix.lower())
app.jinja_env.tests['startwith'] = start_with
if __name__ == '__main__':
    app.run()


测试器.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试器</title>
</head>
<body>
{# 检查变量是否被定义,也可以用undefined检查是否未被定义 #}
{% if name is defined %}
    <p>Name is: {{ name }}</p>
{% endif %}

{% if name is undefined %}
    <p>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 %}

{# 检查数值是否是偶数,也可以用odd检查是否为奇数 #}
{% if 2 is even %}
  <h2>Variable is an even number.</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 %}

<hr>
{% if '10011110000' is isphone %}
    <p>是手机号</p><br>
{% else %}
    <p>不是手机号</p><br>
{% endif %}

{% if 'hello' is startwith('he') %}
    <p>是以he开头</p>
{% endif %}
</body>
</html>

结果

09

5、模板的继承

继承.py

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/extend')
def hello_world():
    return render_template('010child.html')

@app.route('/include')
def to_include():
    return render_template('010include.html')

if __name__ == '__main__':
    app.run()

parent.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父模板</title>
</head>
<body>
{% block temp1 %}
    <p>页面的头部</p>
    <hr>
{% endblock %}

{% block temp2 %}
    <hr>
    <p>页面的尾部</p>
{% endblock %}
</body>
</html>

child.html

{% extends '010parent.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>子模板</title>
</head>
<body>
{% block temp1 %}
    {{ super() }}
    <p>子模板的内容</p>
{% endblock %}
</body>
</html>

结果
010

include.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>include</title>
</head>
<body>
{% include 'header.html' %}
<p>页面中间的内容</p>
{% include 'footer.html' %}
</body>
</html>

header.html

 <p>页面的头部</p>
 <hr>

footer

<hr>
<p>页面的尾部</p>

结果
011

6、模板中使用URL_FOR函数

模版中的 url_for 跟我们后台视图函数中的 url_for 使用起来基本是一模一样的。也是传递视图函数的名字,也

可以传递参数。使用的时候,需要在 url_for 左右两边加上一个 {{ url_for(‘func’) }}

url_for函数.py

from flask import Flask,render_template

app = Flask(__name__)


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

@app.route('/login/<un>')
def user_login(un):
    print(un)
    return f'ok,用户名{un}'

if __name__ == '__main__':
    app.run()

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="{{ url_for('user_login',un='zs',id=2) }}">登录</a>

<img src="{{ url_for('static',filename='7.jpg') }}">

</body>
</html>

进入页面

01201

点击登录

01202
下面的图片为加载的静态资源

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值