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

(1) 原生的表單

模板頁面,form表單form.htmlhtml

<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')

(2) Flask-wtf表單

說明 : 是一個用於表單處理,校驗並提供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類或者其子類,通常有表單類,驗證器類安全

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

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

#按照分級信息彈出不一樣的顯示框
相關文章
相關標籤/搜索