在 Web 开发中,表单用于接收用户输入并提交给服务器进行处理。Flask 提供了多种方式处理表单,其中 Flask-WTF 是最常用的表单库,基于 WTForms,提供了 CSRF 保护、字段验证等功能。
本章将介绍 Flask 表单处理的基础知识,包括:
- 使用 Flask-WTF 处理表单
- 服务器端数据验证
- 处理文件上传
- 防止 CSRF 攻击
5.1 安装 Flask-WTF
首先,我们需要安装 Flask-WTF:
pip install flask-wtf
5.2 配置 Flask-WTF
在 app.py 里:
from flask import Flask
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key' # 保护表单免受 CSRF 攻击
SECRET_KEY 用于生成 CSRF 令牌,确保表单提交安全。
5.3 定义表单类
创建 forms.py,使用 FlaskForm 定义表单:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=3, max=20)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired(), Length(min=6)])
confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Register')
5.4 处理表单提交
在 app.py 里添加表单处理逻辑:
from flask import render_template, redirect, url_for, flash
from forms import RegistrationForm
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
flash(f'Account created for {form.username.data}!', 'success')
return redirect(url_for('home'))
return render_template('register.html', form=form)
5.5 渲染表单
创建 templates/register.html:
<!DOCTYPE html>
<html><head>
<title>Register</title></head><body>
<h2>Register</h2>
<form method="POST">
{{ form.hidden_tag() }} <!-- CSRF 保护 -->
<p>{{ form.username.label }} {{ form.username }}</p>
<p>{{ form.email.label }} {{ form.email }}</p>
<p>{{ form.password.label }} {{ form.password }}</p>
<p>{{ form.confirm_password.label }} {{ form.confirm_password }}</p>
<p>{{ form.submit }}</p>
</form></body>
</html>
5.6 服务器端表单验证
Flask-WTF 提供了多种验证器:
5.6.1 DataRequired - 必填字段
username = StringField('Username', validators=[DataRequired()])
如果字段为空,表单验证会失败。
5.6.2 Length - 长度限制
password = PasswordField('Password', validators=[Length(min=6, max=20)])
确保密码长度在 6-20 之间。
5.6.3 Email - 验证邮箱格式
email = StringField('Email', validators=[Email()])
5.7 处理文件上传
创建 UploadForm 类:
from flask_wtf.file import FileField, FileAllowed
class UploadForm(FlaskForm):
file = FileField('Upload File', validators=[FileAllowed(['jpg', 'png', 'pdf'])])
submit = SubmitField('Upload')
在 app.py 里添加上传处理:
import osfrom flask import request
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
@app.route('/upload', methods=['GET', 'POST'])
def upload():
form = UploadForm()
if form.validate_on_submit():
file = form.file.data
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File uploaded successfully!', 'success')
return redirect(url_for('upload'))
return render_template('upload.html', form=form)
创建 templates/upload.html:
<form method="POST" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<p>{{ form.file.label }} {{ form.file }}</p>
<p>{{ form.submit }}</p>
</form>
5.8 处理 CSRF 保护
Flask-WTF 默认启用 CSRF 保护,每个表单都需要 hidden_tag()。
如果禁用 CSRF 保护,可在 app.config 里设置:
app.config['WTF_CSRF_ENABLED'] = False
5.9 结语
本章介绍了 Flask 表单处理,包括:
- Flask-WTF 表单定义
- 服务器端表单验证
- 处理文件上传
- CSRF 保护
下一章将介绍 Flask 的数据库与模型操作。