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>