文章目录
- 1. 基本表单处理,使用 request.form(轻量)
- 示例一
- 创建 HTML 表单
- 处理表单数据
- 示例二
- HTML 表单(login.html)
- Flask 路由处理表单
- 2. 使用 Flask-WTF 扩展
- 安装
- 设置 Secret Key(CSRF 防护)
- 定义表单类
- HTML 模板(login.html)
- Flask 视图函数
- ✅ 常用字段类型(WTForms)
- ✅ 常用验证器(validators)
- HTML 表单字段中的 URL 验证器
- 总结
- 3.文件上传
- 4.处理文件上传
- 5.AJAX 表单处理
在 Flask 中,表单处理是构建 Web 应用时一个常见的需求。用于处理用户提交的数据,比如登录、注册、搜索等。
- 基本表单处理:使用 request.form 获取表单数据,简单直接
- 使用 Flask-WTF:结合 WTForms 进行表单处理和验证,简化表单操作。表单验证更强大,推荐用于复杂表单。
- 表单验证:使用验证器确保表单数据的有效性。
- 文件上传:处理文件上传和保存文件。
- CSRF 保护:确保表单免受跨站请求伪造攻击。
1. 基本表单处理,使用 request.form(轻量)
示例一
创建 HTML 表单
templates/form.html 文件代码:
<!DOCTYPE html>
<html>
<head><title>Form Example</title>
</head>
<body><form action="/submit" method="post"><label for="name">Name:</label><input type="text" id="name" name="name"><br><label for="email">Email:</label><input type="email" id="email" name="email"><br><input type="submit" value="Submit"></form>
</body>
</html>
action="/submit"
:表单数据提交到 /submit 路径。
method="post"
:使用 POST 方法提交数据。
处理表单数据
app.py 文件代码:
from flask import Flask, render_template, requestapp = Flask(__name__)@app.route('/')
def form():return render_template('form.html')@app.route('/submit', methods=['POST'])
def submit():name = request.form.get('name')email = request.form.get('email')return f'Name: {name}, Email: {email}'if __name__ == '__main__':app.run(debug=True)
request.form.get('name')
和 request.form.get('email')
:获取提交的表单数据。
示例二
HTML 表单(login.html)
<form method="POST" action="/login">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" value="登录">
</form>
Flask 路由处理表单
from flask import Flask, request, render_templateapp = Flask(__name__)@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':# 从表单中获取字段值username = request.form.get('username')password = request.form.get('password')return f"你提交了:{username} / {password}"return render_template('login.html')
2. 使用 Flask-WTF 扩展
安装
pip install flask-wtf
设置 Secret Key(CSRF 防护)
Flask-WTF 自动为表单提供 CSRF 保护。你需要配置一个密钥来启用 CSRF 保护,并在模板中包含隐藏的 CSRF 令牌。
app.config['SECRET_KEY'] = 'your-secret-key'
在模板中添加 CSRF 令牌方式
<form method="post">{{ form.hidden_tag() }}<!-- Form fields here -->
</form>
定义表单类
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequiredclass LoginForm(FlaskForm):username = StringField("用户名", validators=[DataRequired()])password = PasswordField("密码", validators=[DataRequired()])submit = SubmitField("登录")
HTML 模板(login.html)
<form method="POST">{{ form.hidden_tag() }}{{ form.username.label }} {{ form.username() }}<br>{{ form.password.label }} {{ form.password() }}<br>{{ form.submit() }}
</form>
{{ form.hidden_tag() }}
:生成隐藏字段,用于保护表单免受 CSRF 攻击。
{{ form.name.label }}
和 {{ form.name(size=32) }}
:渲染表单字段及其标签。
Flask 视图函数
from flask import render_template
from forms import LoginForm # 假设你表单类定义在 forms.py@app.route('/login', methods=['GET', 'POST'])
def login():form = LoginForm()if form.validate_on_submit():username = form.username.datapassword = form.password.datareturn f"成功提交:{username} / {password}"return render_template('login.html', form=form)
validate_on_submit
:检查是否是POST请求并且验证通过
✅ 常用字段类型(WTForms)
字段 | 含义 |
---|---|
StringField | 文本输入框 |
PasswordField | 密码框 |
SubmitField | 提交按钮 |
TextAreaField | 多行输入框 |
SelectField | 下拉选择 |
BooleanField | 复选框 |
✅ 常用验证器(validators)
验证器 | 说明 |
---|---|
DataRequired() | 必填 |
Length(min, max) | 长度限制 |
Email() | 邮箱格式验证 |
EqualTo() | 两次输入一致,比较两个字段的值(如密码确认) |
NumberRange | 验证数字范围 |
Regexp | 使用正则表达式验证 |
URL | 验证 URL |
from wtforms import Form, StringField, EmailField, SubmitField
from wtforms.validators import DataRequired, Email, Lengthclass MyForm(FlaskForm):name = StringField('Name', validators=[DataRequired(), Length(min=1, max=50)])email = EmailField('Email', validators=[DataRequired(), Email()])password = PasswordField('密码', validators=[DataRequired()])confirm_password = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password')])submit = SubmitField('Submit')
HTML 表单字段中的 URL 验证器
用于 字段的前端验证:
<form><input type="url" name="website" required placeholder="请输入网址"><input type="submit">
</form>
浏览器会自动验证用户输入的内容是否是合法 URL,例如 https://example.com。
总结
用法 | 特点 |
---|---|
request.form | 简单、快速,小项目 OK |
Flask-WTF | 自动验证、安全性高、大项目推荐 |
3.文件上传
Flask 还支持处理文件上传。上传的文件可以通过 request.files 访问。
创建文件上传表单
当你在表单中使用了
<input type="file">
进行文件上传时,必须设置表单的 enctype 属性,如果 没有指定
enctype="multipart/form-data"
,那么上传的文件内容不会正确发送到服务器。
templates/upload.html 文件代码:
<!DOCTYPE html>
<html>
<head><title>Upload File</title>
</head>
<body><form action="/upload" method="post" enctype="multipart/form-data"><label for="file">File:</label><input type="file" id="file" name="file"><br><input type="submit" value="Upload"></form>
</body>
</html>
enctype="multipart/form-data"
:指定表单数据的编码类型,支持文件上传。
enctype 值 | 说明 |
---|---|
application/x-www-form-urlencoded | 默认值。适用于普通表单字段(文本、数字等)。 |
multipart/form-data | 用于上传文件(或含文件字段的表单)。 |
text/plain | 不常用,仅调试用途(不编码特殊字符,不推荐用于实际表单提交)。 |
4.处理文件上传
app.py 文件代码:
from flask import Flask, request, redirect, url_forapp = Flask(__name__)
app.secret_key = 'your_secret_key'@app.route('/upload', methods=['POST'])
def upload():file = request.files.get('file')if file:filename = file.filenamefile.save(f'uploads/{filename}')return f'File uploaded successfully: {filename}'return 'No file uploaded'if __name__ == '__main__':app.run(debug=True)
request.files.get('file')
:获取上传的文件对象。
file.save(f'uploads/{filename}')
:将文件保存到指定目录。
确保创建上传目录并配置上传路径:
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 限制为16MB
5.AJAX 表单处理
@app.route('/api/submit', methods=['POST'])
def api_submit():if request.is_json:data = request.get_json()# 处理数据return jsonify({'status': 'success'})return jsonify({'status': 'error', 'message': 'Invalid request'})