11、flask-模板-templates

模板Templates

模板是呈现给用户的界面
在MVT架构中充当T的角色、实现了MT的解耦、开发中VT有着N:M的关系,一个V可以调用任意T,一个T可以被任意V调用
模板处理分为两个过程:
- 加载HTML
- 模板渲染(模板语言)

模板代码包含两个部分:
- 静态HTML
- 动态插入的代码段(模板语法)

Jinja2 模板语言

在Flask中使用Jinja2模板引擎
Jinja2有Flask作者开发:
    - 一个现代化设计和友好的python模板语言
    - 模仿Django的模板引擎

优点:
- 速度快、被广泛使用
- HTML设计和后端python分离
- 减少python复杂度
- 非常灵活、快速且安全
- 提供了控制、继承等高级功能

 

模板语法

模板语法主要分为两种:
- 变量
- 标签

模板中的变量 {{ var }}
- 视图传递给模板的数据
- 前面定义出来的数据
- 变量不存在、默认忽略

模板中的 标签 {% tag %}
- tag 如:if else for 等等
- 控制逻辑
- 使用外部表达式
- 创建变量
- 宏定义

结构标签

block块操作:
- 父模板挖坑、子模版填坑
{% block xxx %}
{% endblock %}

extends 继承:
{% extends 'xxx' %}

继承后保留块中的内容 
{{ super() }}

include 包含:
- 包含,将其他的html包含进来
{% include 'xxx' %}

marco 函数 - 了解即可
- 宏定义、可以在模板中定义函数、在其他地方调用
{% macro hello(name) %}
    {{ name }}
{% endmacro %}

宏定义可导入
{% form 'xxx' import xxx %}

循环 for

for循环
{%  for item in cols %}
    AA
{% else %}
    BB
{%  endfor %}

- 可以使用和python一样的for...else
也可以获取循环的信息 loop
loop.first:判断使否是第一个元素
loop.last:判断是否是最后一个元素
loop.index:1开始的下标
loop.index0:0开始的下标
loop.revindex:反向下标,不包含0
loop.revindex0:反向下标、包括0

基础案例

views.py

# 路由 + 视图函数

from flask import Blueprint, render_template
# from models import *

#蓝图
# 创建蓝图对象
# 第一个参数:蓝图的名字
# 第二个参数:蓝图的包名
blue = Blueprint('user', __name__,)

@blue.route('/')        # 路由
def home():
    pass

    data = {
        'name': 'ikun',
        'age': 7,
        'gender': '男',
        'likes': ['basketball', 'football', 'swim']
    }

    return render_template('home.html', **data)

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home</title>
</head>
<body>

    <h2>Home</h2>
    <hr>

    {#  注释  #}
    <h4>变量:</h4>
    <p>name: {{ name }}</p>
    <p>age: {{ age }}</p>
    <p>likes: {{ likes }}</p>
    <hr>

    <h4>标签:</h4>
    <h5>if语句</h5>
    {% if age >= 18 %}
        <p>{{ name }}已经成年了</p>

    {% elif age >= 6 %}
        <p>{{ name }}可以上幼儿园了</p>
    {% else %}
        <p>{{ name }}还没成年呢</p>
    {% endif %}
    <hr>

    <h5>for循环</h5>
    {% for like in likes %}
        {% if loop.first %}
            <p style="color: red">{{ like }}</p>
        {% elif loop.last %}
            <p style="color: aqua">{{ like }}</p>
        {% else %}
            <p>{{ like }}</p>
        {% endif %}

        index: {{ loop.index }},
        index0: {{ loop.index0 }},
        index: {{ loop.revindex }},
        index0: {{ loop.revindex0 }},

    {% else %}
        {#如果for循环有问题就执行else块#}
        <b>for...else</b>
    {% endfor %}


</body>
</html>

 

模板语言的高级用法

views.py

# 路由 + 视图函数

from flask import Blueprint, render_template
# from models import *

#蓝图
# 创建蓝图对象
# 第一个参数:蓝图的名字
# 第二个参数:蓝图的包名
blue = Blueprint('user', __name__,)

@blue.route('/')        # 路由
def home():
    pass

    data = {
        'name': 'ikun, xiaoxin, ikun',
        'age': 7,
        'gender': '男',
        'likes': ['basketball', 'football', 'swim']
    }

    # return render_template('home.html', **data)
    # return render_template('base.html')
    # return render_template('child1.html')
    return render_template('child2.html', **data)

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父模板</title>

    {#  通用css文件  #}
    <link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}">
    {% block extcss %}
    {% endblock %}
</head>
<body>

    {% block head %}
    {% endblock %}

    {% block content %}
    {% endblock %}

    {% block footer %}
    {% endblock %}

    {#  通用的js文件  #}
    <script src="{{ url_for('static', filename='js/base.js') }}"></script>
    {% block extjs %}
    {% endblock %}


</body>
</html>

child1.html


{#直接继承base.html即可#}
{% extends 'base.html' %}

{#继承后直接在head中写内容即可#}
{% block head %}
    <div>
        <p>xiaoxin YYDS</p>
    </div>
{% endblock %}

child2.html


{#继承父模板child1#}
{% extends 'child1.html' %}

{#继承后如果不加super()写会覆盖掉父模板的head块,加了super()会保留父模板的head块#}
{% block head %}
    {{ super() }}
    <p>
        python
    </p>
{% endblock %}

{# include #}
{% block content %}
    {#  将模板文件引入  #}
    {% include 'child2_include.html' %}
    <p>flask content</p>
{% endblock %}

{# 宏定义 #}
{% macro person(name, age) %}
    <b>姓名:{{ name }},年龄:{{ age }}</b>
{% endmacro %}

{% block footer %}
    {#  调用宏定义函数并将参数传进去  #}
    {{ person('张三', 18) }}

    {#  过滤器  #}
    <p>{{ name | capitalize }}</p>
    <p>{{ name | title }}</p>
    <p>{{ name | upper }}</p>
    <p>{{ name | lower }}</p>
    <p>{{ name | upper | first | lower }}</p>
    <p>{{ name2 | default('如果name2不存在就显示默认值') }}</p>
{% endblock %}

child2_include.html

<div>我是child2中include中的内容</div>

 

posted @ 2024-07-07 22:04  little小新  阅读(33)  评论(0编辑  收藏  举报