本系列筆記是我閱讀Miguel Grinberg的《Flask Web Development》的筆記,標題與書本同步。希望通過記錄技術(shù)筆記的方式促進自己對知識的理解。本篇對應(yīng)書本第四章:Web表單。
安裝Flask-WTF包
(venv) $ pip install flask-wtf
跨站請求偽造保護
hello.py: 配置 Flask-WTF
app = Flask(__name__) # 實例化Flask
app.config['SECRET_KEY'] = 'hard to guess string
# 設(shè)置app配置變量config的值
# 為了增加安全性,密鑰不應(yīng)該寫死在代碼中,而要在保存在環(huán)境變量中
表單類
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標準字段:可直接調(diào)用相應(yīng)的HTML
| 字段類型 | 說明 |
|---|---|
| StringField | 文本字段 |
| TextAreaField | 多行文本字段 |
| PasswordField | 密碼文本字段 |
| HiddenField | 隱藏文本字段 |
| DateField | 文本字段,值為datetime.date格式 |
| DateTimeField | 文本字段,值為datetime.datetime格式 |
| IntegerField | 文本字段,值為整數(shù) |
| DecimalField | 文本字段,值為decimal.Decimal |
| FloatField | 文本字段,值為浮點數(shù) |
| BooleanField | 復(fù)選框,值為True和False |
| RadioField | 一組單選框 |
| SelectField | 下拉列表 |
| SelectMultipleField | 下拉列表,可以選多個值 |
| FileField | 文件上傳字段 |
| SubmitField | 表單提交按鈕 |
| FormField | 把表單作為字段嵌入另一個表單 |
| FieldList | 一組指定類型字段 |
WTForms內(nèi)建的驗證函數(shù)
WTForms驗證函數(shù): 可直接調(diào)用驗證相應(yīng)要求的字段
| 驗證函數(shù) | 說明 |
|---|---|
| 驗證Email | |
| EqualTo | 比較兩個字段的值 |
| IPAddress | 驗證IPv4網(wǎng)絡(luò)地址 |
| Length | 驗證長度 |
| NumberRange | 數(shù)字范圍 |
| Optional | 無輸入值時跳過其他函數(shù) |
| Required | 確保不為空 |
| Regexp | 使用正則驗證輸入值 |
| URL | 驗證URL |
| AnyOf | 確保輸入值在可選的列表中 |
| NoneOf | 確保輸入值不在可選的列表中 |
把表單渲染成HTML
Flask-Bootstrap提供了一個輔助函數(shù),使用Bootstrap預(yù)先定義好的表單樣式渲染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由兩部分組成:頁面歡迎信息、表單
在視圖函數(shù)中處理表單
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() 會驗證所有用戶提交的數(shù)據(jù)。符合這返回True

Flask-WTF Web表單

提交后顯示的Web表單

驗證失敗后顯示的Web表單
重定向和用戶會話
為了防止莫名的警告,最后一個請求不能是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參數(shù)的值。當值不存在時返回None,不是返回異常。
Flash消息
一般請求完成后,需要用戶知道狀態(tài)發(fā)生了變化,就像是確認信息,錯誤信息,警告,提示,之類的。這種功能就是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()函數(shù)獲取的信息在下次調(diào)用時不會再次返回,只顯示一次就消失。
本文由 EverFighting 創(chuàng)作,采用 **知識共享署名 3.0 中國大陸許可協(xié)議 **進行許可。
可自由轉(zhuǎn)載、引用,但需署名作者且注明文章出處。