title: 利用pycharm學(xué)習(xí)flask(八)
date: 2016-10-04 15:36:58
tags: python
category: python
本文內(nèi)容:
1.跨站請(qǐng)求偽造保護(hù)
2.表單類
3.把表單渲染成HTML
4.在視圖函數(shù)中處理表單
跨站請(qǐng)求偽造保護(hù)
Flask-WTF是一個(gè)擴(kuò)展,可以幫助我們處理web表單隐绵,我們跟前面一樣在pycharm中安裝它潦刃。
默認(rèn)情況下摹迷,F(xiàn)lask-WTF能保護(hù)所有表單免受跨站請(qǐng)求偽造的攻擊。Flask-WTF需要程序設(shè)置一個(gè)密匙曲梗。Flask-WTF使用這個(gè)密匙生成加密令牌夸溶,再用令牌驗(yàn)證請(qǐng)求中表單數(shù)據(jù)的真?zhèn)巍?/p>
修改hello.py:
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
其中app.config字典用來(lái)存儲(chǔ)框架、擴(kuò)展和程序本身的配置變量宛乃。使用標(biāo)準(zhǔn)的字典句法就能把配置值添加到app.config對(duì)象中。
表單類
使用Flask-WTF時(shí)蒸辆,每個(gè)Web表單都由一個(gè)繼承自Form的類表示征炼。這個(gè)類定義表單中的一組字段,每個(gè)字段都用對(duì)象表示躬贡。字段對(duì)象可附屬一個(gè)或多個(gè)驗(yàn)證函數(shù)谆奥。驗(yàn)證函數(shù)用來(lái)驗(yàn)證用戶提交的輸入值是否符合要求。
修改hello.py拂玻,定義表單類:
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import Required
class NameForm(FlaskForm):
name = StringField('What is your name?',validators=[Required()])
submit = SubmitField('Submit')
這個(gè)表單中的字段都定義為類變量酸些,類變量的值是相應(yīng)字段類型的對(duì)象。NameForm表單中有一個(gè)名為name的文本字段和一個(gè)名為submit的提交按鈕檐蚜。StringField類表示屬性為type=“text”的input元素魄懂。SubmitField類表示屬性為type="submit"的input元素。
WTForms支持的HTML標(biāo)準(zhǔn)字段
字段類型 | 說(shuō) 明 |
---|---|
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PasswordField | 密碼文本字段 |
HiddenField | 隱藏文本字段 |
DateField | 文本字段闯第,值為 datetime.date 格式 |
DateTimeField | 文本字段市栗,值datetime.datetime格式 |
IntegerField | 文本字段,值為整數(shù) |
DecimalField | 文本字段咳短,值為 decimal.Decimal |
FloatField | 文本字段肃廓,值為浮點(diǎn)數(shù) |
BooleanField | 復(fù)選框,值為 True 和 False |
RadioField | 一組單選框 |
SelectField | 下拉列表 |
SelectMultipleField | 下拉列表诲泌,可選擇多個(gè)值 |
FileField | 文件上傳字段 |
SubmitField | 表單提交按鈕 |
FormField | 把表單作為字段嵌入另一個(gè)表單 |
FieldList | 一組指定類型的字段 |
WTForms驗(yàn)證函數(shù)
驗(yàn)證函數(shù) | 說(shuō) 明 |
---|---|
驗(yàn)證電子郵件地址 | |
EqualTo | 比較兩個(gè)字段的值;常用于要求輸入兩次密碼進(jìn)行確認(rèn)的情況 |
IPAddress | 驗(yàn)證 IPv4 網(wǎng)絡(luò)地址 |
Length | 驗(yàn)證輸入字符串的長(zhǎng)度 |
NumberRange | 驗(yàn)證輸入的值在數(shù)字范圍內(nèi) |
Optional | 無(wú)輸入值時(shí)跳過(guò)其他驗(yàn)證函數(shù) |
Required | 確保字段中有數(shù)據(jù) |
Regexp | 使用正則表達(dá)式驗(yàn)證輸入值 |
URL | 驗(yàn)證 URL |
AnyOf | 確保輸入值在可選值列表中 |
NoneOf | 確保輸入值不在可選值列表中 |
把表單渲染成HTML
Flask-Bootstrap 提供了一個(gè)非常高端的輔助函數(shù),可以使用Bootstrap中預(yù)先定義好的表單樣式渲染整個(gè) Flask-WTF表單铣鹏,而這些操作只需一次調(diào)用即可完成敷扫。使用Flask-Bootstrap,上述表單可使用下面的方式渲染:
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
import指令的使用方法和普通Python代碼一樣,允許導(dǎo)入模板中的元素并用在多個(gè)模板中葵第。導(dǎo)入的bootstrap/wtf.html文件中定義了一個(gè)使用Bootstrap渲染 Falsk-WTF表單對(duì)象的輔助函數(shù)绘迁。wtf.quick_form() 函數(shù)的參數(shù)為Flask-WTF表單對(duì)象,使用Bootstrap的默認(rèn)樣式渲染傳入的表單卒密。
修改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 %}
模板的內(nèi)容區(qū)現(xiàn)在有兩部分。第一部分是頁(yè)面頭部哮奇,顯示歡迎消息膛腐。Jinja2中的條件語(yǔ)句格式為{% if condition %}...{% else %}...{% endif %}。如果條件的計(jì)算結(jié)果為T(mén)rue鼎俘,渲染if和else指令之間的值哲身。如果計(jì)算結(jié)果為False,則渲染else和endif指令之間的值贸伐。在上述例子中勘天,如果沒(méi)有定義模板變量name,則渲染字符串"Hello捉邢,Stranger!"脯丝。內(nèi)容區(qū)的第二部分使用wtf.quick_form()函數(shù)渲染NameForm對(duì)象。
在視圖函數(shù)中處理表單
視圖函數(shù)index不僅要渲染表單伏伐,還要接收表單中的數(shù)據(jù)宠进,修改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',from=from,name=name)
其中app.route修飾器中添加的methods參數(shù)告訴flask在url映射中把這個(gè)視圖函數(shù)注冊(cè)為GET和POST請(qǐng)求的處理程序,如果沒(méi)有這個(gè)參數(shù)秘案,默認(rèn)為GET請(qǐng)求砰苍。
局部變量name存儲(chǔ)表單中的名字,如果沒(méi)有輸入就為NONE阱高,創(chuàng)建了一個(gè)NameForm類實(shí)例用于表示表單赚导。提交表單后,如果數(shù)據(jù)能被所有驗(yàn)證函數(shù)接受赤惊,那么validate_on_submit方法返回True吼旧,否則返回False。這個(gè)值決定是重新渲染表單還是處理表單提交的數(shù)據(jù)未舟。
第一次訪問(wèn)時(shí)圈暗,服務(wù)器收到一個(gè)沒(méi)有表單數(shù)據(jù)的GET請(qǐng)求,所以validate_on_submit返回False裕膀。if語(yǔ)句將被跳過(guò)员串,通過(guò)渲染模板處理請(qǐng)求,并傳入表單對(duì)象和值為None的name變量作為參數(shù)昼扛。用戶在瀏覽器中顯示了一個(gè)表單寸齐。
提交表單后,服務(wù)器收到GET請(qǐng)求,validate_on_submit調(diào)用name字段上的Required驗(yàn)證函數(shù)渺鹦。如果名字不為空扰法,就通過(guò)。validate_on_submit返回True毅厚。用戶輸入的名字可以通過(guò)字段的data屬性獲取塞颁。
在if語(yǔ)句中,把名字復(fù)制給name吸耿,然后再把data屬性設(shè)為空字符串祠锣,從而清空表單字段。最后一行調(diào)用render_template函數(shù)渲染模板珍语,但這次參數(shù)name的值為表單中輸入的名字锤岸,因此會(huì)顯示一個(gè)針對(duì)該用戶的歡迎消息。