1. 程式人生 > >Flask入門 表單Flask-wtf form原生 Bootstrap渲染(七)

Flask入門 表單Flask-wtf form原生 Bootstrap渲染(七)

pat 接收數據 功能 rom dir 繼承 gist 視圖 uic

(1) 原生的表單

模板頁面,form表單form.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中

#原生表單
@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‘)

(2) Flask-wtf表單

說明 : 是一個用於表單處理,校驗並提供csrf驗證的功能的擴展庫

安裝 :

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類或者其子類,一般有表單類,驗證器類

  1. 表單類主要有以下幾種:
字段類型 字段說明
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 驗證器一般有以下幾種:

  • 基本上每一個validator都有message參數,指出當輸入數據不符合validator要求時顯示什麽信息
驗證器函數 說明
DataRequired/Required 代表內容是必填項 DataRequired(message=‘用戶信息不能為空‘)
Email 驗證電子郵件地址,要求正則模式 : ^.+@([^.@][^@]+)$
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 確保輸入值不在可選值列表中

實例wtf表單

模板文件 form.html

<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 驗證

(3) 使用bootstrap快速渲染

安裝

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 % }

(4) 重定向和用戶會話(Post/重定向/Get 模式)

基於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請求對應字段數據

(5) Flash消息

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">&times;</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 %}

#按照分級信息彈出不同的顯示框

Flask入門 表單Flask-wtf form原生 Bootstrap渲染(七)