【Flask/跟着學習】Flask大型教程項目#02:web表單

跟着學習:http://www.pythondoc.com/flask-mega-tutorial/webforms.html
回顧上一章:https://blog.csdn.net/weixin_41263513/article/details/85000957

本章內容

  • 配置
  • 表單類
  • 把表單渲染成HTML
  • 在視圖函數中處理表單

上一章編寫的模板都是單向的,所有信息都從服務器流向用戶。
然而,對多數應用來說,還需要沿相反的方向流動信息,把用戶提供的數據交給服務器來處理。

使用HTML可以創建Web表單,供用戶填寫信息。表單數據由Web瀏覽器提交給服務器,這一過程通常使用POST請求,對包含表單數據的POST請求來說,用戶填寫的信息通過request.form訪問

配置

許多 Flask 擴展需要大量的配置,因此我們將要在 microblog 文件夾的根目錄下創建一個配置文件以至於容易被編輯。

爲了能夠處理 web 表單,我們將使用 Flask-WTF ,該擴展封裝了 WTForms 並且恰當地集成進 Flask 中。

Flask-WTF只需要兩個配置
CSRF_ENABLED 配置是爲了激活 跨站點請求僞造 (CSRF)保護。在大多數情況下,你需要激活該配置使得你的應用程序更安全些。

SECRET_KEY 配置僅僅當 CSRF 激活的時候才需要,它是用來建立一個加密的令牌,用於驗證一個表單。當你編寫自己的應用程序的時候,請務必設置很難被猜測到密鑰。

文件:/config.py

class Config(object):
    CSRF_ENABLED = True
    SECRET_KEY = 'you-will-never-guess'

既然我們有了配置文件,我們需要告訴 Flask 去讀取以及使用它。我們可以在 Flask 應用程序對象被創建後去做
文件:/app/–init–.py

from flask import Flask
from config import Config

app = Flask(__name__)
app.config.from_object(Config)

from app import routes

表單類

使用Flask-WTF時,在服務器端,每個web表單都有一個繼承自FlaskForm的類表示,這個類定義表單中的一組字段,每個字段都用對象表示。字段對象可附屬一個或多個驗證函數。驗證函數用於驗證用戶提交的數據是否有效。

我們將在表單上提供一個 ‘remember me’ 的選擇框,以至於用戶可以選擇在他們的網頁瀏覽器上種植 cookie ,當他們再次訪問的時候,瀏覽器能夠記住他們的登錄。

字段構造函數的第一個參數時把表單渲染成HTML時使用的標註(label)
WTForms支持的HTML標準字段 + WTForms內建的驗證函數

文件:/app/forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    username = StringField('用戶名', validators=[DataRequired()])
    password = PasswordField('密碼', validators=[DataRequired()])
    remember_me = BooleanField('記住我')
    submit = SubmitField('登陸')

把表單渲染成HTML

表單字段時可調用的,在模板中調用後會渲染成HTML
表單中還有鴿form.hidden_tag()字段,這個元素生成一個隱藏的字段,供Flask-WTF的CSRF防護機制使用
文件:/app/templates/login.html

{% extends "base.html" %}

{% block content %}
    <h1>Sign In</h1>
    <form action="" method="post" novalidate>
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
        <p>{{ form.submit() }}</p>
    </form>
{% endblock %}

在視圖函數中處理表單

Flask-WTF 使得工作變得簡單的另外一點就是處理提交的數據。這裏是我們登錄視圖函數更新的版本,它驗證並且存儲表單數據,要使用GET和POST請求方法處理Web表單
文件:/app/routes.py

from flask import render_template, flash, redirect, url_for
from app import app
from app.forms import LoginForm
''''''
''''''
@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        flash('用戶:{},恭喜你成功註冊'.format(form.username.data))
        return redirect(url_for('index'))
    return render_template('login.html',  title='Sign In', form=form)

validate_on_submit 方法做了所有表單處理工作。當表單正在展示給用戶的時候調用它,它會返回 False.

如果 validate_on_submit 在表單提交請求中被調用,它將會收集所有的數據,對字段進行驗證,如果所有的事情都通過的話,它將會返回 True,表示數據都是合法的。這就是說明數據是安全的,並且被應用程序給接受了。

如果至少一個字段驗證失敗的話,它將會返回 False,接着表單會重新呈現給用戶,這也將給用戶一次機會去修改錯誤。我們將會看到當驗證失敗後如何顯示錯誤信息。

當 validate_on_submit 返回 True,我們的登錄視圖函數調用了兩個新的函數,導入自 Flask。
flash 函數是一種快速的方式下呈現給用戶的頁面上顯示一個消息。在我們的例子中,我將會使用它來調試,因爲我們目前還不具備用戶登錄的必備的基礎設施,相反我們將會用它來顯示提交的數據。flash 函數在生產服務器上也是十分有作用的,用來提供反饋給用戶有關的行動。
redirect函數告訴網頁瀏覽器引導到一個不同的頁面而不是請求的頁面。在我們的視圖函數中我們用它重定向到前面已經完成的首頁上。要注意地是,閃現消息將會顯示即使視圖函數是以重定向結束。

閃現的消息將不會自動地出現在我們的頁面上,我們的模板需要加入展示消息的內容。我們將添加這些消息到我們的基礎模板中,這樣所有的模板都能繼承這個函數。這是更新後的基礎模板
文件:/app/templates/base.html

<html>
    <head>
        {% if title %}
        <title>{{ title }} - Microblog</title>
        {% else %}
        <title>Welcome to Microblog</title>
        {% endif %}
    </head>
    <body>
        <div>
            Microblog:
            <a href="{{ url_for('index') }}">Home</a>
            <a href="{{ url_for('login') }}">Login</a>
        </div>
        <hr>
        {% with messages = get_flashed_messages() %}
        {% if messages %}
        <ul>
            {% for message in messages %}
            <li>{{ message }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </body>
</html>

結果圖
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章