4.2 表单类
from flask_wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required, EqualTo
# 定义一个表单类
class NameForm(Form):
name=StringField('what is you name', validators=[Required()]) # 创建一个type=text的input
submit=SubmitField('Submit') # 创建一个type=submit的input
conPassword=StringField('confirm password', validators=[EqualTo('password', message='must match')]) # message好像必须有
WTForms支持的HTML标准字段
字段类型 | 说明 |
---|---|
StringField | 文本字段: input type="text" |
TextAreaField | 多行文本字段: textarea元素 |
PasswordField | 密码文本字段 |
HiddenField | 隐藏文本字段 |
DateField | 文本字段,值为datetime.date格式 |
DateTimeField | 文本字段,值为datetime.datetime格式 |
IntergerField | 文本字段,值为整数 |
DecimalField | 文本字段,十进制,值为decimal.Deciamal |
FloatField | 文本字段,值为浮点数 |
BooleanField | 复选框,值为True或者False |
RadioField | 一组单选框,实例见下 |
SelectField | 下拉列表,实例见下 |
SelectMultipleField | 多选下拉列表 |
FileField | 文件上传字段 |
SubmitField | 表单提交按钮 |
FormField | 把表单作为一个字段嵌入另一个表单 |
FieldList | 一组制定类型的字段 |
几个比较特殊的字段示意:
class NameForm(Form):
radioSex=RadioField('性别', choices=[('1', '男人'), ('2', '女人')])
selectHobby=SelectField('爱好', choices=[('3', '足球'), ('4', '篮球'), ('5', '乒乓')])
# radioSex: 表单radio元素的name值
# 第一个引号内: label值
# choises=[]: 数组内'1'为value值
WTFroms验证函数
验证函数 | 说明 |
---|---|
验证电子邮件地址 | |
EqualTo | 比较两个字段的值,例如两次密码验证 |
IPAddress | 验证IPv4网络地址 |
Length | 验证输入字符串的长度 |
NumberRange | 验证输入的值在数字范围内 |
Optional | 无输入值时跳过验证其他函数 |
Required | 确保字段有数据 |
Regexp | 使用正则验证输入值 |
URL | 验证URL |
AnyOf | 确保输入值在可选值列表中 |
NoneOf | 确保输入值不再可选值列表中 |
4.3 将表单渲染成HTML
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky2b{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>
</div>
{#使用flask-bootstrap渲染表单#}
{{ wtf.quick_form(form) }}
{% endblock %}
4.4 在视图函数中处理表单
# -*- coding:utf-8 -*-
# 把 str 编码由 ascii 改为 utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
# 以下载入包
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_moment import Moment # 引入flask-moment
from datetime import datetime # 引入datetime
from flask_wtf import Form
from wtforms import StringField,SubmitField,TextAreaField,IntegerField,BooleanField,RadioField,SelectField,FileField,PasswordField
from wtforms.validators import Required, email, EqualTo
app = Flask(__name__)
app.config['SECRET_KEY']="string hard"
bootstrap=Bootstrap(app)
moment=Moment(app)
# 定义一个表单类
class NameForm(Form):
name=StringField('what is you name', validators=[Required()]) # 创建一个type="text"的input,文本传入label标签
password=PasswordField('password')
conPassword=StringField('confirm password', validators=[EqualTo('password', message='must match')])
intro=TextAreaField('introduce yourself')
email=StringField('input your email', validators=[email()]) # 必须是email格式
integer=IntegerField('input an integer')
booleanC=BooleanField('choose/let')
radioSex=RadioField('性别', choices=[('1', '男人'), ('2', '女人')]) # 创建type="radio"单选框
selectHobby=SelectField('爱好', choices=[('3', '足球'), ('4', '篮球'), ('5', '乒乓')]) #创建select下拉框
submit=SubmitField('Submit') # 创建一个type="submit"的input
fileload=FileField('上传文件')
# 在视图函数中处理表单
@app.route('/', methods=['GET', 'POST'])
def hello_world(): # 在视图函数中要定义name变量和form变量
name=None
intro=None
form=NameForm() # 实例化一个NameForm()类
if form.validate_on_submit(): # 表单验证成功,validate_on_submit()方法返回True
name=form.name.data #
intro=form.intro.data
form.name.data=''
return render_template("form.html",
name=name,
intro=intro,
current_time=datetime.utcnow(),
form=form,
)
if __name__ == '__main__':
app.run(debug=True)
4.5 重定向和用户会话
不要让web程序将POST请求作为浏览器发送的最后一个请求;
使用重定向后,原先的name=form.name.data
获取的数据就丢失了,所以要将数据存储在用户会话中,session
from flask import Flask, render_template, session, redirect, url_for
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
session['name'] = form.name.data
return redirect(url_for('index')) # 生成HTTP重定向响应,参数是重定向的URL
return render_template('index.html', form=form, name=session.get('name'))
# 使用.get('name')读取避免未找到键的异常情况
4.6 flash消息
在视图函数中使用flash()会生成一个消息,Flask把get_flashed_messages()函数开放给模板,用于模板中获取并渲染消息
{% block content %}
<div class='container'>
{% for message in get_flashed_messages() %}
<div class='alert alert-warning'>
<button type='button' class='close' data-dismiss='alert'>×</button>
{{ message }}
</div>
{% endfor %}
</div>
{% endblock %}
from flask import Flask,render_template,session,redirect,url_for,flash
@app.route('/',mrthod=['GET', 'POST'])
def index():
form=NameForm()
if form.validate_on_submit():
old_name=session.get('name')
if old_name is not None and old_name != form.name.data:
flash('you changed your name!')
session('name')=form.name.data
return redirect(url_for('index'))
return render_template('index.html', form=form, name=session.get('name'))