Web 表單是用戶交互的核心入口。本文基於 Flask-WTF 擴展,詳細講解表單定義、驗證、模板渲染、數據接收與 OpenID 登錄集成的完整流程,助你快速構建安全可靠的表單系統。
安裝 Flask-WTF 後,在專案根目錄建立 config.py:
CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'
初始化應用時載入配置(app/__init__.py):
from flask import Flask
app = Flask(__name__)
app.config.from_object('config')
from app import views
建立 app/forms.py,繼承 Form 基類:
from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required
class LoginForm(Form):
openid = TextField('openid', validators=[Required()])
remember_me = BooleanField('remember_me', default=False)
TextField:文本輸入框,綁定 Required 驗證器防止空提交BooleanField:複選框,「記住我」功能預設關閉Flask-WTF 內建多種驗證器(如 Email、Length、Regexp 等),後續章節將逐步應用。
建立 app/templates/login.html,繼承基礎佈局:
{% extends "base.html" %}
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" name="login">
{{ form.hidden_tag() }}
<p>
Please enter your OpenID:<br>
{{ form.openid(size=80) }}<br>
</p>
<p>{{ form.remember_me }} Remember Me</p>
<p><input type="submit" value="Sign In"></p>
</form>
{% endblock %}
關鍵點解析:
{{ form.hidden_tag() }}:CSRF 保護必需的隱藏字段{{ form.field_name }}:自動渲染對應 HTML 控件,支援屬性傳參(如 size=80)app/views.py 中定義路由:
from flask import render_template, flash, redirect
from app import app
from forms import LoginForm
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data))
return redirect('/index')
return render_template('login.html', title='Sign In', form=form)
methods=['GET', 'POST']:允許雙向請求validate_on_submit():核心方法,僅在 POST 提交且驗證通過時返回 Trueflash():閃現消息,下一請求顯示(需在基礎模板渲染)redirect():重導向至首頁更新 base.html 顯示 flash 訊息:
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
當驗證失敗時,錯誤訊息存於 form.errors.字段名,模板中遍歷顯示:
{{ form.openid(size=80) }}
{% for error in form.errors.openid %}
<span style="color: red;">[{{error}}]</span>
{% endfor %}<br>
紅色樣式增強可見性,用戶即時了解輸入問題。
在 config.py 定義常用提供商:
OPENID_PROVIDERS = [
{'name': 'Google', 'url': 'https://www.google.com/accounts/o8/id'},
{'name': 'Yahoo', 'url': 'https://me.yahoo.com'},
{'name': 'AOL', 'url': 'https://openid.aol.com/'},
{'name': 'Flickr', 'url': 'https://www.flickr.com/'},
{'name': 'MyOpenID', 'url': 'https://www.myopenid.com'}
]
視圖函數傳遞給模板:
return render_template('login.html', title='Sign In', form=form, providers=app.config['OPENID_PROVIDERS'])
模板中渲染連結,配合 JavaScript 處理需用戶名的提供商:
<script type="text/javascript">
function set_openid(openid, pr) {
u = openid.search('')
if (u != -1) {
user = prompt('Enter your ' + pr + ' username:')
openid = openid.substr(0, u) + user
}
form = document.forms['login'];
form.elements['openid'].value = openid
}
</script>
...
|{% for pr in providers %}
<a href="javascript:set_openid('{{pr.url}}', '{{pr.name}}');">{{pr.name}}</a> |
{% endfor %}
用戶點擊連結即自動填充 OpenID,極大降低輸入門檻。
本章完整實踐了 Flask 表單開發全流程:
validate_on_submit() 統一處理驗證邏輯flash + redirect 實現提交後反饋掌握這套模式,即可應對多數 Web 表單場景。下一章將引入數據庫持久化,讓用戶數據真正落地。