本系列笔记是我阅读Miguel Grinberg的《Flask Web Development》的笔记,标题与书本同步。希望通过记录技术笔记的方式促进自己对知识的理解。本篇对应书本第四章:Web表单。
安装Flask-WTF包
(venv) $ pip install flask-wtf
跨站请求伪造保护
hello.py: 配置 Flask-WTF
app = Flask(__name__) # 实例化Flask
app.config['SECRET_KEY'] = 'hard to guess string
# 设置app配置变量config的值
# 为了增加安全性,密钥不应该写死在代码中,而要在保存在环境变量中
表单类
hello.py: 定义表单类
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
# 定义了一个文本字段和一个提交按钮
WTForms支持的HTML标准字段
HTML标准字段:可直接调用相应的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内建的验证函数
WTForms验证函数: 可直接调用验证相应要求的字段
验证函数 | 说明 |
---|---|
验证Email | |
EqualTo | 比较两个字段的值 |
IPAddress | 验证IPv4网络地址 |
Length | 验证长度 |
NumberRange | 数字范围 |
Optional | 无输入值时跳过其他函数 |
Required | 确保不为空 |
Regexp | 使用正则验证输入值 |
URL | 验证URL |
AnyOf | 确保输入值在可选的列表中 |
NoneOf | 确保输入值不在可选的列表中 |
把表单渲染成HTML
Flask-Bootstrap提供了一个辅助函数,使用Bootstrap预先定义好的表单样式渲染Flask-Wtf表单对象,使用Bootstrap默认样式渲染传入的表单。
templates/index.html:使用Flask-WTF和Flask-Bootstrap渲染表单
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>
</div>
{{ wtf.quick_form(form) }}
{% endblock %}
# page_content由两部分组成:页面欢迎信息、表单
在视图函数中处理表单
hello.py: 路由方法
@app.route('/', methods=['GET', 'POST'])
def index():
name = None
form = NameForm()
if form.validate_on_submit():
name = form.name.data
form.name.data = ''
return render_template('index.html', form=form, name=name)
# 新增了POST方法,提交表单POST请求处理会更便利
# validate_on_submit() 会验证所有用户提交的数据。符合这返回True
重定向和用户会话
为了防止莫名的警告,最后一个请求不能是POST,故改成Post/重定向/Get模式。
from flask import Flask, render_template, session, redirect, url_for
@app.route('/',method=['GET','POST'])
def index():
form = NameForm()
if form.validate_on_submit():
session['name'] = form.name.data
return redirect(url_for('index'))
return render_template('index.html',form=form,name=session.get('name'))
# session.get('name') 会从会话中读取name参数的值。当值不存在时返回None,不是返回异常。
Flash消息
一般请求完成后,需要用户知道状态发生了变化,就像是确认信息,错误信息,警告,提示,之类的。这种功能就是Flah消息的核心特性。
hello.py: Flash消息
from flask import Flask,render_template, session, redirect, url_for, flash
@app.route('/', methods=['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.date:
flash('Looks like you have changed your name!')
session['name'] = form.name.data
return redirect(url_for('index'))
return render_template('index.html',form=form, name=session.get('name'))
templates/base.html: 渲染Flash信息
{% 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 %}
{% block page_content %}{% endblock %}
</div>
{% endblock %}
# get_flashed_messages()函数获取的信息在下次调用时不会再次返回,只显示一次就消失。
本文由 EverFighting 创作,采用 **知识共享署名 3.0 中国大陆许可协议 **进行许可。
可自由转载、引用,但需署名作者且注明文章出处。