原生表单
HTML部分
raw_form.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="" method="post"><label >用户名</label><input type="text" name="username"><br><label >密码</label><input type="password" name="password" ><br><input type="submit" value="注册" /></form></body></html>
视图函数部分
hello.py
from flask import Flask, render_template, requestapp = Flask(__name__)@app.route("/", methods=["GET", "POST"])def index():if request.method == "POST":username = request.form.get('username')password = request.form.get('password')return render_template("raw_form.html", username=username)return render_template('raw_form.html')if __name__ == "__main__":app.run(debug=True)
flask-wtf
简介|安装包
优点
- 可以抵制CSRF跨站请求伪造的攻击,更具安全性
- 减少重复编写表单HTML
- 提供丰富的表单校验方法
使用
定义表单
# 1、配置密匙from flask import Flaskapp = Flask(__name__)app.config['SECRET_KEY'] = 'XXXX'# 2、导包使用from flask_wtf import FlaskForm #web表单都从该类继承from wtforms import StringField, SubmitField #字段from wtforms.validators import DataRequired #字段校验#定义表单类class NameForm(FlaskForm):name = StringField('Name:' validators=[DataRequired()]) #第一个参数将函数构造成label;可以多个校验同时生效,所以为list类型submit = SubmitField('submit')
视图函数
#...同上@app.route("/", methods=['GET', 'POST'])def index():form = NameForm()return render_template('index.html', form=form)
获取表单值
# 表单对象获取name = form.name.data# request 对象获取name = request.form.get("name")
form对象渲染表单
<form method='POST'>{{ form.hidden_tag() }} # 生成一个隐藏字段,供Flask-WTF的CSRF机制使用{{ form.name.label }} {{ form.name(id='test') }} # 渲染name字段并为其添加属性{{ form.submit() }}</form>
flask-bootstrap渲染表单
# 需要在原视图函数中注册Bootstrap ,否则在渲染时候报错找不到bootstrap/wtf.htmlform flask_bootstrap import Bootstrapbootstrap = Bootstrap(app)
单字段渲染
{% import 'bootstrap/wtf.html' as wtf %}{{ wtf.form_field(form.name, class="form-control text-body") }}
快速渲染
{% import 'bootstrap/wtf.html' as wtf %}{{ wtf.quick_form(form) }}
WTForms支持的HTML标准字段
| 字段类型 | 说明 | eg | | —- | —- | —- | | StringField | 文本字段 | | | TextAreaField | 多行文本字段 | | | PasswordField | 密码文本字段 | | | HiddenField | 隐藏文本字段 | | | DateField | 文本字段,值为datatime.date格式 | | | DateTimeField | 文本字段,值为datatime.datetime格式 | | | IntegerField | 文本字段,值为整数 | | | DecimalField | 文本字段,值为 decimal.Decimal | | | FloatField | 文本字段,值为浮点数 | | | BooleanField | 复选框,值为 True 和 False | | | RadioField | 一组单选框 | | | SelectField | 下拉列表 | SelectField(label=”请选择环境”, choices=[(1, “无锡”), (7, “HK”), (4, “AWSCA”)], default=1, coerce=int) | | SelectMultipleField | 下拉列表,可选择多个值 | | | FileField | 文件上传字段 | | | SubmitField | 表单提交按钮 | | | FormField | 把表单作为字段嵌入另一个表单 | | | FieldList | 一组指定类型的字段 | |
WTForms支持的验证函数
| 方法名 | 说明 |
|---|---|
| DataRequired | 确保转换类型后字段中有数据 |
| InputRequired | 确保转换类型前字段中有数据 |
| 验证电子邮件地址 | |
| EqualTo | 比较两个字段的值;常用于要求输入两次密码进行确认的情况 |
| IPAddress | 验证 IPv4 网络地址 |
| Length | 验证输入字符串的长度 |
| MacAddress | 验证Mac地址 |
| UUID | 验证UUID |
| NumberRange | 验证输入的值在数字范围内 |
| Optional | 无输入值时跳过其他验证函数 |
| Regexp | 使用正则表达式验证输入值 |
| URL | 验证 URL |
| AnyOf | 确保输入值在可选值列表中 |
| NoneOf | 确保输入值不在可选值列表中 |
拓展
表单中添加图标
.user-icon {padding-left:30px;background-repeat: no-repeat;background-position-x: 4px;background-position-y: 4px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAYAAAArdgcFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA+5pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ1dWlkOjY1RTYzOTA2ODZDRjExREJBNkUyRDg4N0NFQUNCNDA3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIzOUVGMUYxMDY3MTExRTI5OUZEQTZGODg4RDc1ODdCIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIzOUVGMUYwMDY3MTExRTI5OUZEQTZGODg4RDc1ODdCIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMTgwMTE3NDA3MjA2ODExODA4M0ZFMkJBM0M1RUU2NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNjgwMTE3NDA3MjA2ODExODA4M0U3NkRBMDNEMDVDMSIvPiA8ZGM6dGl0bGU+IDxyZGY6QWx0PiA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPmdseXBoaWNvbnM8L3JkZjpsaT4gPC9yZGY6QWx0PiA8L2RjOnRpdGxlPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkX/peQAAACrSURBVHja7JSLCYAwDEQbJ3AER+kouoFu0FEcqSM4gk4QE4ggVRPxg1A8OFCSvkqC5xDRaSZ5ciTjyvzuzbMnwKjY34FHAx618yCQXQHAcVFE5+GoVijgyt3UN1/+hPKFd0a9ubxQa6naMjOdOY2jJAdjZIH7tJ8gzRNuZuho5MriUfpLNbhINXk4Cd27pN3AJVqvQlMPSxSz+oegqXuQhz9bNvDpJfY0CzAA6Ncngv5RALIAAAAASUVORK5CYII=);}
然后在模板里渲染时传入这个类:
<form method="POST">{{ form.hidden_tag() }}{{ wtf.form_field(form.username, class="form-control user-icon") }}{{ wtf.form_field(form.password) }}{{ wtf.form_field(form.submit) }}</form>
