本系列筆記是我閱讀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
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參數的值。當值不存在時返回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 中國大陸許可協議 **進行許可。
可自由轉載、引用,但需署名作者且注明文章出處。