模板頁面,form表單form.html
html
<form action="{{ url_for('/check/') }}" method='post'> <p>用戶名: <input type='text' name='username'></p> <p>密碼: <input type='password' name='userpass'></p> <p><input type='submit' value='submit'></p> </form>
在manage.py中python
#原生表單 @app.route('/form') def form(): return render_template('form.html') #獲取原生表單提交的數據 @app.route('/check',method=['POST']) def check(): print(request.form.get('userpass')) print(request.form.get('username')) return '提交數據' #注: 第一個form函數僅僅是跳轉頁面做用,比較浪費所以咱們能夠合併一下
在manage.py中將路由函數合併正則表達式
@app.route('/form') def form(): if request.method == 'POST': print(request.form.get('userpass')) print(request.form.get('username')) return render_template('/form.html')
說明 : 是一個用於表單處理,校驗並提供csrf驗證的功能的擴展庫flask
安裝 :bootstrap
sudo pip3 install flask-wtf
做用: Flask-wtf能保護全部表單免受跨站請求僞造的攻擊(Cross-Site Request Forgery,CSRF),惡意網站會把請求發送到被攻擊者登陸的其餘網站就會引發CSRF攻擊,所以咱們須要實現CSRF保護機制,Flask-wtf採用的作法是爲程序設置一個祕鑰,Flask-WTF 使用這個密鑰生成加密令牌,再用令牌驗證請求中表單數據的真僞。瀏覽器
app = Flask(__name__) app.config['SECRET_KEY'] = 'sadad131[]' #採用字典的方式存儲框架,擴展和程序自己的配置變量,通常祕鑰不直接寫入代碼,放在環境變量增長安全性.
flask-wtf通常自定義的表單類都是繼承自Form類或者其子類,通常有表單類,驗證器類安全
字段類型 | 字段說明 |
---|---|
StringField | 普通文本字段 |
TextAreaField | 多行文本字段 |
SubmitField | 提交 |
PasswordField | 密碼字段 |
HiddenField | 隱藏文本字段 |
DateField | 日期字段 datetime.date(year=2018,month=2,day=20) 2018-02-20 |
DateTimeFiled | 時間字段 datetime.datetime(year=2018,month=2,day=20) 2018-02-20 00:00:00 |
IntegerField | 文本字段,值爲整數 |
FloatField | 文本字段,值是浮點數 |
DecimalField | 文本字段,值爲 decimal.Decimal |
BooleanField | 複選框,值爲 True 和 False |
RadioField | 一組單選框 choices = [('w','女'),('m','男')] 參數1做爲傳遞,參數2位顯示值 |
SelectField | 下拉列表 choices參數肯定了下拉選項, 是一個tuple組成的列表 (同上) |
SelectMultipleField | 下拉列表,可選擇多個值 |
FileField | 文件上傳字段 |
FormField | 把表單做爲字段嵌入另外一個表單 |
Validator是驗證函數,把一個字段綁定驗證函數以後,flask在接受表單以前會作一個驗證 , 若是驗證成功纔會接收數據。驗證函數Validator以下,服務器
2 驗證器通常有如下幾種:網絡
驗證器函數 | 說明 |
---|---|
DataRequired/Required | 表明內容是必填項 DataRequired(message='用戶信息不能爲空') |
驗證電子郵件地址,要求正則模式 : ^.+@([^.@][^@]+)$ |
|
EqualTo | 比較兩個字段的值,經常使用於確認密碼狀況 EqualTo('要確認字段名',message='xxx') |
IPAddress | 驗證IPV4網絡地址 參數默認ipv4=True,ipv6=False |
Length | 驗證輸入字符串的長度 參數類型是字符串Length(min=6,max=30,message='我的信息的簡介6-30個字') |
NumberRange | 驗證輸入的值在數字範圍內NumberRange(min=6,max=90,message='年齡爲6-90歲') |
Optional | 無輸入值時跳過其餘驗證函數 |
Regexp | 使用正則表達式驗證輸入值 參數regex='正則模式' |
URL | 驗證 URL URL(message='請輸入正確的url地址')] 正則模式是^[a-z]+://(?P<host>[^/:]+)(?P<port>:[0-9]+)?(?P<path>\/.*)?$ |
AnyOf | 確保輸入值在可選值列表中 |
NoneOf | 確保輸入值不在可選值列表中 |
模板文件 form.htmlsession
<form action="{{ url_for('wtf_form') }}" method='post'> {{ form.csrf_token }} #進入csrf驗證 <p>{{ form.username.label }}{{ form.username(style='color:red',placeholder='請輸入用戶名') }}{{ form.username.errors }}</p> <p>{{ form.userpass.label }}{{ form.userpass() }}{{ form.userpass.errors }}</p> <p>{{ form.submit() }}</p> </form> #經過form.字段名獲取對應字段屬性 form.字段名(修飾符)
manage.py文件中
from flask import Flask,render_template,request from flask_wtf import FlaskForm #導入繼承父類 from wtforms import StringField,PasswordField,SubmitField from wtforms.validators import Length,DataRequired class Login(FlaskForm): #繼承自FlaskForm類 username = StringField('用戶名',validators=[Length(min=6,max=12,message='用戶名長度爲6~12位'),DataRequired(message='用戶名不能爲空')]) userpass = PasswordField('密碼',validators=[Length(min=6,max=12,message='密碼長度爲6~12位'),DataRequired(message='密碼不能爲空')]) submit = SubmitField('登陸') @app.route('/wtf_form',methods=['GET','POST']) def wtf_form(): form = Login() #實例化form對象 if request.method == 'POST': if form.validate_on_submit(): #數據正確 而且驗證csrf經過 print(request.form.get('userpass')) print(request.form.get('username')) return '數據提交成功' return render_template('wtf_form.html',form=form) #注: #1 methods 參數告訴Flask在URL映射中把這個視圖函數註冊爲GET和POST請求的處理程序,默認GET #2 採用post請求能夠經過對象很輕鬆訪問,GET 請求沒有主體,提交的數據以查詢字符串的形式附加到URL中 #3 validate_on_submit() 會調用username 字段上附屬的 DataRequired() 驗證函數。
注意: 1 form.validate_on_submit() 只有在數據正確 而且驗證csrf經過 返回True
2 {{ form.csrf_token }} 進入表單 csrf 驗證
安裝
pip3 install flask-bootstrap
視圖函數:導入與實例
from flask_bootstrap import Bootstrap #導入 bootstrap = Bootstrap(app) #綁定bootstrap與該項目app的關係
導入 :基本用到的模板爲 base.html 繼承基類 和wtf.html 導入宏
{% import 'bootstrap/wtf.html' as wtf %} #導入重命名爲wtf {{ wtf.quick_form(form,url_for('index')) }} #訪問宏wtf.quick_form('數據',路由) {{ wtf.quick_form(form) }}
可使用 Bootstrap 中預先定義好的表單樣式渲染整個 Flask-WTF 表單。導入模板中的bootstrap/wtf.html 元素。定義了一個使用 Bootstrap 渲染 Falsk-WTF 表單對象的輔助函數。 wtf.quick_form() 函數的參數爲 Flask-WTF 表單對象,使用 Bootstrap 的默認樣式渲染傳入的表單。
index.html
{ % extends "base.html" % } #繼承base.html,必須寫在最前面 { % import "bootstrap/wtf.html" as wtf % } #重命名wtf { % block title % }首頁{ % endblock % } { % block page_content % } #定義內容 <div class="page-header"> <h1>Hello, { % if username % }{{ username }}{ % else % }Stranger{ % endif % }!</h1> </div> {{ wtf.quick_form(form) }} #傳入表單對象 { % endblock % }
基於Web程序把POST請求做爲瀏覽器發送的最後一個請求,這種需求的實現方式是,使用重定向做爲 POST 請求的響應,而不是使用常規響應。可是請求結束以後form.username.data接受的數據爲用戶輸入的名字也就丟失了.所以咱們採起將數據存儲放在用戶會話session中.
from flask import Flask,render_template,session,redirect,url_for @app.route('/',methods=['GET','POST']) def index(): form = Login() if form.validate_on_submit(): #判斷request是個帶POST數據,且數據符合表單定義要求 session['username'] = form.username.data #將username保存到session return redirect(url_for('index')) #重定向到'index視圖函數路由' return render_template('index.html',form=form,name=session.get['username']) #注: <表單對象名>.<Field名稱>.data 能夠訪問POST請求對應字段數據
Flask的核心特性Flash實現: 爲了解決用戶提交了有一項錯誤的登陸表單後,服務器發回的響應從新渲染了登陸表單,並在表單上面顯示一個消息,提示用戶用戶名或密碼錯誤。經常用於表單信息提示.
flash()
做用是每次調用flash()都會觸發一個消息因此可能有多個消息在排隊等待顯示。
get_flashed_messages()
函數獲取傳入的消息 其實就是一個列表, 獲取的消息在下次調用時不會再次返回,所以 Flash 消息只顯示一次,而後就消失了。
使用
from flask import flask,get_flashed_messages @app.route('/register/',method=['GET','POST']) def register(): form = Register() if form.validate_on_submit(): flash('註冊成功') return redirect(url_for('index')) return render_template('form.html',form=form)
在模板中獲取
{% for message in get_flashed_messages() %} <div class="alert alert-success alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <strong>success!</strong>{{ message }} </div> {% endfor %}
flash使用固然不只僅限於單一消息的傳遞,flash的源碼定義爲 :
def flash(message, category='message'):
所以能夠看到不只能傳遞消息message
還能將傳遞的消息進行類別category
選擇
get_flashed_messages一樣有接受信息類別的屬性with_categories=
設置爲True
def get_flashed_messages(with_categories=False, category_filter=[]):
例如
if content.split('\n') <= 2: flash(message=u'警告',category='warning') elif content.split('\n') >= 5: flash(message=u'不容許的操做',category='danger') {% block content %} {% for category,message in get_flashed_message(with_category=True) %} <div class="alert alert-{{ category }} alert-dismissable"> <button type="button" class="close" data-dismiss="alert">&tims;</button> {{ message }} </div> {% endfor %} {% endblock %} #按照分級信息彈出不一樣的顯示框