在Web開發中,表單是用戶與應用交互的重要方式,比如用戶註冊、登錄、提交評論等功能都依賴表單。Flask本身沒有內置表單處理功能,但藉助Flask-WTF擴展(基於WTForms庫),我們可以輕鬆實現表單的定義、驗證和提交。本文將從基礎開始,帶你掌握Flask中使用WTForms處理表單的核心知識點。
一、安裝依賴¶
首先,需要安裝Flask-WTF擴展(它已集成了WTForms,無需單獨安裝)。打開命令行,執行:
pip install flask-wtf
二、WTForms常用字段類型¶
WTForms提供了多種預定義的字段類型,對應HTML的不同輸入控件。以下是初學者最常用的幾種:
| WTForms字段 | HTML對應類型 | 功能描述 |
|---|---|---|
StringField |
<input type="text"> |
單行文本輸入(如用戶名、郵箱) |
PasswordField |
<input type="password"> |
密碼輸入(自動隱藏輸入內容) |
SubmitField |
<input type="submit"> |
提交按鈕 |
IntegerField |
<input type="number"> |
整數輸入 |
BooleanField |
<input type="checkbox"> |
複選框(True/False值) |
RadioField |
<input type="radio"> |
單選按鈕組 |
SelectField |
<select> |
下拉菜單 |
三、定義表單類¶
在Flask中,我們通過繼承FlaskForm類定義表單,並在類中聲明具體字段。例如,創建一個簡單的登錄表單:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email # 導入驗證器
class LoginForm(FlaskForm):
# 用戶名:標籤爲“用戶名”,必填(DataRequired),長度3-20字符(Length)
username = StringField('用戶名', validators=[
DataRequired(message='用戶名不能爲空'),
Length(min=3, max=20, message='用戶名長度需3-20字符')
])
# 郵箱:標籤爲“郵箱”,必填且格式驗證(Email)
email = StringField('郵箱', validators=[
DataRequired(message='郵箱不能爲空'),
Email(message='請輸入有效的郵箱地址')
])
# 密碼:標籤爲“密碼”,必填
password = PasswordField('密碼', validators=[
DataRequired(message='密碼不能爲空')
])
# 提交按鈕
submit = SubmitField('登錄')
關鍵點:
- FlaskForm是Flask-WTF提供的基類,繼承它即可創建表單。
- validators參數用於定義字段驗證規則(如必填、長度限制、格式驗證),DataRequired表示字段不能爲空,Email驗證郵箱格式。
- 字段名(如username)是Python變量名,標籤字符串(如’用戶名’)會在模板中顯示。
四、視圖函數處理表單¶
表單需要在視圖函數中處理GET(首次加載)和POST(提交數據)兩種請求。核心步驟:
1. 創建表單實例。
2. 檢查是否爲POST請求且數據驗證通過(form.validate_on_submit())。
3. 驗證通過則處理數據(如保存到數據庫);否則顯示錯誤信息。
示例代碼:
from flask import Flask, render_template, redirect, url_for
from forms import LoginForm # 導入剛纔定義的LoginForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here' # 必須設置,用於CSRF保護(生產環境需隨機複雜密鑰)
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm() # 創建表單實例
if form.validate_on_submit(): # 檢查是否爲POST且數據合法
# 獲取表單數據(通過.data屬性)
username = form.username.data
email = form.email.data
password = form.password.data
# 這裏可以處理數據(如驗證登錄、保存用戶信息)
print(f"用戶登錄:{username}, {email}")
return redirect(url_for('success')) # 提交成功後跳轉
return render_template('login.html', form=form) # 渲染模板,傳遞表單對象
@app.route('/success')
def success():
return "登錄成功!"
if __name__ == '__main__':
app.run(debug=True)
五、模板渲染表單¶
模板需要渲染表單,並處理提交和錯誤信息。使用Flask-WTF的模板工具可以簡化表單渲染,核心是:
- form.hidden_tag():自動生成CSRF保護令牌(必須添加,否則表單提交會被攔截)。
- 循環form.errors顯示錯誤信息。
創建templates/login.html:
<!DOCTYPE html>
<html>
<head>
<title>用戶登錄</title>
<style>
.error { color: red; } /* 錯誤信息樣式 */
.form-group { margin-bottom: 10px; }
</style>
</head>
<body>
<h1>用戶登錄</h1>
<!-- 渲染表單,提交方式爲POST -->
<form method="post">
{{ form.hidden_tag() }} <!-- CSRF保護令牌 -->
<!-- 用戶名 -->
<div class="form-group">
{{ form.username.label }}<br>
{{ form.username(size=30) }} <!-- 生成<input type="text"> -->
{% for error in form.username.errors %}
<span class="error">{{ error }}</span> <!-- 顯示錯誤信息 -->
{% endfor %}
</div>
<!-- 郵箱 -->
<div class="form-group">
{{ form.email.label }}<br>
{{ form.email(size=30) }}
{% for error in form.email.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
</div>
<!-- 密碼 -->
<div class="form-group">
{{ form.password.label }}<br>
{{ form.password(size=30) }}
{% for error in form.password.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
</div>
<!-- 提交按鈕 -->
{{ form.submit() }}
</form>
</body>
</html>
關鍵點:
- form.hidden_tag()會生成一個隱藏的<input>標籤,用於CSRF防護,必須包含。
- form.username.label生成字段標籤(如“用戶名”),form.username(size=30)生成文本輸入框。
- form.errors是一個字典,存儲每個字段的錯誤信息,通過循環顯示。
六、核心原理總結¶
- 表單定義:通過
FlaskForm子類聲明字段和驗證規則。 - 請求處理:視圖函數區分GET(顯示空表單)和POST(驗證提交數據)。
- 數據驗證:
form.validate_on_submit()自動運行所有驗證器(必填、格式等),通過後獲取數據。 - 模板渲染:
form對象自動生成HTML表單元素,結合模板循環顯示錯誤信息。 - CSRF保護:
form.hidden_tag()生成令牌,防止跨站請求僞造攻擊。
七、常見問題與解決¶
- “CSRF token missing”錯誤:確保
form.hidden_tag()在模板中,且app.config['SECRET_KEY']已設置。 - 表單驗證不通過:檢查
validators是否正確配置,錯誤信息在form.errors中。 - 密碼輸入未隱藏:使用
PasswordField而非StringField,它會自動渲染爲<input type="password">。
通過以上步驟,你已掌握Flask表單處理的核心:定義字段、處理請求、驗證數據和渲染表單。後續可結合數據庫(如SQLAlchemy)存儲表單數據,或添加更多字段類型(如單選按鈕、下拉菜單)實現複雜交互。