Flask后端笔记(三)Jinja2模板、过滤器、表单、宏、模板继承、包含
Flask后端笔记
- Jinja2模板
- 基本流程
- 变量
- 过滤器
- 字符串过滤器
- 支持链式使用过滤器
- 列表过滤器
- 自定义过滤器
- 表单
- 不使用Flask-WTF扩展时,表单需要自己处理
- 使用Flask-WTF扩展
- 控制语句
- if语句
- for语句
- 宏
- 不带参数宏的定义与使用
- 带参数宏的定义与使用
- 将宏单独封装在html文件中
- 模板继承
- 包含(Include)
- Flask中的特殊变量和方法
- config 对象:
- request 对象:
- url_for 方法:
- get_flashed_messages方法:
Jinja2模板
基本流程
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Template</title>
</head>
<body><h1>hello {{ name }}</h1>
</body>
</html>
@app.route("/")
def index():return render_template("index.html", name="python")
使用flask 中的render_template渲染模板
变量
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><p>name = {{ name }}</p><p>age = {{ age }}</p><p>my_dict: city= {{ my_dict["city"] }}</p><p>my_dict: city= {{ my_dict.city }}</p><p>my_list: {{ my_list }}</p><p>my_list[my_int]: {{ my_list[my_int] }}</p><p>my_list[0] + my_list[1] = {{ my_list[0] + my_list[1] }}</p><p>{{"hello" + " python" }}</p><p>a{{" flask world " | trim | upper }}a</p><hr/><p>{{my_list | li2 }}</p><p>{{my_list | li3 }}</p>
</body>
</html>
# coding:utf-8from flask import Flask, render_templateapp = Flask(__name__)@app.route("/index")
def index():data = {"name": "python","age": 18,"my_dict": {"city": "sz"},"my_list": [1, 2, 3, 4, 5],"my_int": 0}return render_template("index.html", **data)def list_step_2(li):"""自定义的过滤器"""return li[::2]# 注册过滤器
app.add_template_filter(list_step_2, "li2")@app.template_filter("li3")
def list_step_3(li):"""自定义的过滤器"""return li[::3]if __name__ == '__main__':app.run(debug=True)
过滤器
字符串过滤器
safe:禁用转义;<p>{{ '<em>hello</em>' | safe }}</p>capitalize:把变量值的首字母转成大写,其余字母转小写;<p>{{ 'hello' | capitalize }}</p>lower:把值转成小写;<p>{{ 'HELLO' | lower }}</p>upper:把值转成大写;<p>{{ 'hello' | upper }}</p>title:把值中的每个单词的首字母都转成大写;<p>{{ 'hello' | title }}</p>trim:把值的首尾空格去掉;<p>{{ ' hello world ' | trim }}</p>reverse:字符串反转;<p>{{ 'olleh' | reverse }}</p>format:格式化输出;<p>{{ '%s is %d' | format('name',17) }}</p>striptags:渲染之前把值中所有的HTML标签都删掉;<p>{{ '<em>hello</em>' | striptags }}</p>
支持链式使用过滤器
<p>{{ “ hello world “ | trim | upper }}</p>
列表过滤器
first:取第一个元素<p>{{ [1,2,3,4,5,6] | first }}</p>last:取最后一个元素<p>{{ [1,2,3,4,5,6] | last }}</p>length:获取列表长度<p>{{ [1,2,3,4,5,6] | length }}</p>sum:列表求和<p>{{ [1,2,3,4,5,6] | sum }}</p>sort:列表排序<p>{{ [6,2,3,1,5,4] | sort }}</p>
自定义过滤器
自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。
方式一:
通过 add_template_filter (过滤器函数, 模板中使用的过滤器名字)
方式二:
通过装饰器 app.template_filter (模板中使用的装饰器名字)
表单
使用Flask-WTF表单扩展,可以帮助进行CSRF验证,帮助我们快速定义表单模板,而且可以帮助我们在视图中验证表的数据
pip install Flask-WTF
不使用Flask-WTF扩展时,表单需要自己处理
#模板文件
<form method='post'><input type="text" name="username" placeholder='Username'><input type="password" name="password" placeholder='password'><input type="submit">
</form>
from flask import Flask,render_template,request@app.route('/login',methods=['GET','POST'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']print username,passwordreturn “success”else:return render_template(“login.html”)
使用Flask-WTF扩展
需要设置 SECRET_KEY 的配置参数
模板页:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form method="post">{{ form.csrf_token }}{{ form.user_name.label }}<p>{{form.user_name}}</p>{% for msg in form.user_name.errors %}<p>{{msg}}</p>{% endfor %}{{ form.password.label }}<p>{{form.password}}</p>{% for msg in form.password.errors %}<p>{{msg}}</p>{% endfor %}{{ form.password2.label }}<p>{{form.password2}}</p>{% for msg in form.password2.errors %}<p>{{msg}}</p>{% endfor %}{{form.submit}}</form>
</body>
</html>
视图函数
#coding=utf-8
from flask import Flask, render_template, redirect, url_for, session#导入wtf扩展的表单类
from flask_wtf import FlaskForm
#导入自定义表单需要的字段
from wtforms import SubmitField,StringField,PasswordField
#导入wtf扩展提供的表单验证器
from wtforms.validators import DataRequired,EqualTo
app = Flask(__name__)
app.config['SECRET_KEY']='xhosd6f982yfhowefy29f'#自定义表单类,文本字段、密码字段、提交按钮# 定义表单的模型类
class RegisterForm(FlaskForm):"""自定义的注册表单模型类"""# 名字 验证器/验证器# DataRequired 保证数据必须填写,并且不能为空user_name = StringField(label=u"用户名", validators=[DataRequired(u"用户名不能为空")])password = PasswordField(label=u"密码", validators=[DataRequired(u"密码不能为空")])password2 = PasswordField(label=u"确认密码", validators=[DataRequired(u"确认密码不能为空"),EqualTo("password", u"两次密码不一致")])submit = SubmitField(label=u"提交")#定义根路由视图函数,生成表单对象,获取表单数据,进行表单数据验证@app.route("/register", methods=["GET", "POST"])
def register():# 创建表单对象, 如果是post请求,前端发送了数据,flask会把数据在构造form对象的时候,存放到对象中form = RegisterForm()# 判断form中的数据是否合理# 如果form中的数据完全满足所有的验证器,则返回真,否则返回假if form.validate_on_submit():# 表示验证合格# 提取数据uname = form.user_name.datapwd = form.password.datapwd2 = form.password2.dataprint(uname, pwd, pwd2)session["user_name"] = unamereturn redirect(url_for("index"))return render_template("register.html", form=form)@app.route("/index")
def index():user_name = session.get("user_name", "")return "hello %s" % user_nameif __name__ == '__main__':app.run(debug=True)
WTForms支持的HTML标准字段
字段对象 | 说明 |
---|---|
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PasswordField | 密码文本字段 |
HiddenField | 隐藏文本字段 |
DateField | 文本字段,值为datetime.date格式 |
DateTimeField | 文本字段,值为datetime.datetime格式 |
IntegerField | 文本字段,值为整数 |
DecimalField | 文本字段,值为decimal.Decimal |
FloatField | 文本字段,值为浮点数 |
BooleanField | 复选框,值为True和False |
RadioField | 一组单选框 |
SelectField | 下拉列表 |
SelectMultipleField | 下拉列表,可选择多个值 |
FileField | 文本上传字段 |
SubmitField | 表单提交按钮 |
FormField | 把表单作为字段嵌入另一个表单 |
FieldList | 一组指定类型的字段 |
WTForms常用验证函数
验证函数 | 说明 |
---|---|
DataRequired | 确保字段中有数据 |
EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
Length | 验证输入的字符串长度 |
NumberRange | 验证输入的值在数字范围内 |
URL | 验证URL |
AnyOf | 验证输入值在可选列表中 |
NoneOf | 验证输入值不在可选列表中 |
控制语句
if语句
{% if %} {% endif %}
for语句
{% for item in samples %} {% endfor %}
宏
类似于python中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余。
不带参数宏的定义与使用
定义:
{% macro input() %}<input type="text"name="username"value=""size="30"/>
{% endmacro %}
使用
{{ input() }}
带参数宏的定义与使用
定义
{% macro input(name,value='',type='text',size=20) %}<input type="{{ type }}"name="{{ name }}"value="{{ value }}"size="{{ size }}"/>
{% endmacro %}
使用
{{ input(value='name',type='password',size=40)}}
将宏单独封装在html文件中
文件名可以自定义macro.html
{% macro input() %}<input type="text" name="username" placeholde="Username"><input type="password" name="password" placeholde="Password"><input type="submit">
{% endmacro %}
在其它模板文件中先导入,再调用
{% import 'macro.html' as func %}
{% func.input() %}
模板继承
与django一致
模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。
{% block top %}``{% endblock %}标签定义的内容,相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充。
子模板使用extends指令声明这个模板继承自哪?父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()
父模板:base.html
{% block top %}顶部菜单{% endblock top %}{% block content %}{% endblock content %}{% block bottom %}底部{% endblock bottom %}
子模板:
{% extends 'base.html' %}{% block content %}需要填充的内容{% endblock content %}
模板继承使用时注意点:
- 不支持多继承。
- 为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。
- 不能在一个模板文件中定义多个相同名字的block标签。
- 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。
包含(Include)
Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。它的功能是将另一个模板整个加载到当前模板中,并直接渲染。
示例:
include的使用
{\% include 'hello.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上ignore missing关键字。如果包含的模板文件不存在,会忽略这条include语句。
示例:
include的使用加上关键字ignore missing
{\% include 'hello.html' ignore missing %}
宏、继承、包含:
- 宏(Macro)、继承(Block)、包含(include)均能实现代码的复用。
- 继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。
- 宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。
- 包含(include)是直接将目标模板文件整个渲染出来。
Flask中的特殊变量和方法
在Flask中,有一些特殊的变量和方法是可以在模板文件中直接访问的。
config 对象:
config 对象就是Flask的config对象,也就是 app.config 对象。{{ config.SQLALCHEMY_DATABASE_URI }}
request 对象:
就是 Flask 中表示当前请求的 request 对象,request对象中保存了一次HTTP请求的一切信息。
request常用的属性如下:
属性 | 说明 | 类型 |
---|---|---|
data | 记录请求的数据,并转换为字符串 | * |
form | 记录请求中的表单数据 | MultiDict |
args | 记录请求中的查询参数 | MultiDict |
cookies | 记录请求中的cookie信息 | Dict |
headers | 记录请求中的报文头 | EnvironHeaders |
method | 记录请求使用的HTTP方法 | GET/POST |
url | 记录请求的URL地址 | string |
files | 记录请求上传的文件 | * |
{{ request.url }}
url_for 方法:
url_for() 会返回传入的路由函数对应的URL,所谓路由函数就是被 app.route() 路由装饰器装饰的函数。如果我们定义的路由函数是带有参数的,则可以将这些参数作为命名参数传入。
{{ url_for('index') }}{{ url_for('post', post_id=1024) }}
get_flashed_messages方法:
返回之前在Flask中通过 flash() 传入的信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出。
闪现只能看到一次
{% for message in get_flashed_messages() %}{{ message }}
{% endfor %}
Flask后端笔记(三)Jinja2模板、过滤器、表单、宏、模板继承、包含相关推荐
- Flask后端笔记(二)request、bort、响应、session、钩子
Flask后端笔记 获取请求参数 上传文件 _with的使用 bort函数与自定义异常处理 abort函数 自定义异常处理 返回的响应数据 元组 make_response json模块的使用 使用j ...
- 如何通过云模板创建表单?丨三叠云教程
三叠云官网https://www.sandieyun.com/ 1. 简介 1.1 功能简介 云模板中心是表单的共享中心,里面承载着众多三叠云接入企业所提供的优秀成熟的表单案例,内容详尽,范围涵盖各行 ...
- 前端_网页编程 Form表单与模板引擎(中)
目录 ... ... (续上篇) 四.模板引擎的基本概念 1.定义 2. 优点 五.art-template模板引擎 1.art-template模板引擎介绍 2. art-template的安装 3 ...
- 前端_网页编程 Form表单与模板引擎(上)
目录 一.form表单的基本使用 1. 什么是表单? 2. 表单的组成部分 3. < form>标签的基本属性 3.1 action 3.2 target 3.3 method 3.4 e ...
- flask 模板:控制语句 、宏、继承、包含、特殊变量和方法【闪现使用】
一.控制语句 if语句 {% if %} {% endif %} for语句 {% for item in samples %}{% endfor %} 二.宏 1.不带参数 类似于python中的函 ...
- 前端_网页编程 Form表单与模板引擎(下)
目录 续上一篇 6. 模板引擎的实现原理 6.1 正则与字符串操作 6.1.1 基本语法 6.1.2 分组 6.1.3 字符串的replace函数 6.1.4 多次replace 6.1.5 使用wh ...
- angularjs 表单校验指令_angular4.0的模板式表单、响应式表单及其错误提示
模板式表单 NgForm.NgModel.NgModelGroup是FormModule里的内容,NgForm会自动拦截标准的表单处理事件(eg.提交),angular用ngSubmit代替标准的表单 ...
- form表单与模板引擎
form表单与模板引擎 一.form表单的基本使用 1.1 什么是表单 1.2 表单的组成部分 1.3 <form>标签的属性 1.4 表单的同步提交及缺点 二.通过ajax提交表单数据 ...
- Form表单及模板引擎
Form表单及模板引擎 什么是Form表单 Form表单的一些属性 表单的同步提交及优缺点 通过Ajax提交表单数据 JQuery的监听表单提交事件 取消表单默认提交行为 快速获取表单中的数据 模板引 ...
最新文章
- 由Python历史「解密」Python底层逻辑
- SAP RETAIL 寄售模式公司间STO收发货过账后的观察
- mysql连接,修改密码,增加用户,显示,导入导出
- 使用yum管理软件包
- Solaris下调整opt分区的inode结构
- java实现频繁集_数据挖掘--频繁集测试--Apriori算法--java实现
- native固定吸顶 react_React Native固定底部TextInput,解决键盘遮挡、列表滚动问题
- Redis 05_List列表 数组 Hash散列
- 算法运行时间中的对数
- Java EE CDI bean范围
- 11. 列表标签及其应实例
- vue 在js 文件中使用store_vue 如何在 .js 文件引入 store
- R语言chorolayer_R成精系列-R 错误汇总
- 2021年中国磁感应芯片市场趋势报告、技术动态创新及2027年市场预测
- 用Python写一个简单的监控系统
- ubuntu16.04下FastDFS+Nginx分布式文件系统
- Sixpack —— 支持多语言的 A/B 测试框架
- 如何让gitbook与github仓库关联
- 苹果ipad怎么刷机_苹果手机:iOS12刷机iOS12正式版刷机教程
- 高刷新率电视机有必要吗?
热门文章
- uniapp 一个小程序跳转另一个小程序跳转过来的
- 怎么在电脑上玩手游绝地求生:刺激战场?刺激战场PC电脑版攻略
- Web hooks/web 钩子详解
- 日期类型的时间加减计算
- Vue入门之组件化开发
- window10下安装git的详细步骤
- fossa网络库_如何升级到Ubuntu 20.04 Focal Fossa
- [USACO5.3]量取牛奶Milk Measuring
- 分布式-4分布式集群
- wifi因服务器停止响应,如果浏览器由于服务器停止响应而无法打开网页,该怎么办...