本文章致力于让读者尽可能多的掌握 WTForms 的使用方法,希望每个初学者都能理解。
一、WTForms 是什么?
WTForms 是一个 Python 库,专门用来处理网页表单。它能帮你:
- 轻松创建表单
- 验证用户输入的数据
- 防止恶意数据提交
- 简化表单代码
二、安装 WTForms
打开命令行(Windows 的 cmd 或 Mac 的终端),输入:
pip install WTForms
安装完成后,就可以在 Python 中使用它了。
三、最简单的表单例子
让我们从一个最简单的登录表单开始:
from wtforms import Form, StringField, PasswordField
# 定义一个登录表单类
class LoginForm(Form):
username = StringField('用户名') # 用户名输入框
password = PasswordField('密码') # 密码输入框
代码解释:
LoginForm(Form)
:创建一个表单类,继承自Form
StringField
:文本输入框PasswordField
:密码输入框(输入内容会显示为圆点)'用户名'
:字段的标签(显示在输入框前面的文字)
四、如何使用这个表单
在 Flask 中使用这个表单:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(request.form) # 创建表单实例
if request.method == 'POST' and form.validate(): # 如果是POST请求且数据有效
username = form.username.data # 获取用户名
password = form.password.data # 获取密码
# 这里可以添加登录逻辑
return f"欢迎 {username}!登录成功"
# 显示表单页面
return render_template('login.html', form=form)
if __name__ == '__main__':
app.run()
代码解释:
request.form
:获取用户提交的表单数据form.validate()
:检查表单数据是否有效form.username.data
:获取用户输入的用户名
五、创建对应的 HTML 模板
在 templates/login.html
文件中:
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>用户登录</h1>
<form method="POST">
{{ form.hidden_tag() }} <!-- 隐藏字段,用于安全防护 -->
<p>
{{ form.username.label }}<br>
{{ form.username(size=20) }} <!-- 用户名输入框 -->
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=20) }} <!-- 密码输入框 -->
</p>
<p><input type="submit" value="登录"></p>
</form>
</body>
</html>
代码解释:
{{ form.hidden_tag() }}
:自动生成隐藏的安全字段{{ form.username.label }}
:显示"用户名"标签{{ form.username() }}
:显示用户名输入框size=20
:设置输入框宽度为20个字符
六、添加表单验证
现在我们的表单没有验证规则,让我们添加一些:
from wtforms.validators import DataRequired, Length
class LoginForm(Form):
username = StringField('用户名', [
DataRequired(message='用户名不能为空'),
Length(min=4, max=20, message='用户名长度必须在4到20个字符之间')
])
password = PasswordField('密码', [
DataRequired(message='密码不能为空'),
Length(min=6, message='密码至少需要6个字符')
])
验证器解释:
DataRequired
:字段不能为空Length
:限制输入长度message
:验证失败时显示的错误信息
七、显示验证错误信息
修改 HTML 模板显示错误信息:
<form method="POST">
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=20) }}
{% if form.username.errors %}
<ul>
{% for error in form.username.errors %}
<li style="color: red;">{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=20) }}
{% if form.password.errors %}
<ul>
{% for error in form.password.errors %}
<li style="color: red;">{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
<p><input type="submit" value="登录"></p>
</form>
八、常用字段类型
WTForms 提供了多种字段类型:
字段类型 | 描述 | 示例 |
---|---|---|
StringField | 普通文本输入 | 用户名、姓名 |
PasswordField | 密码输入 | 密码、确认密码 |
TextAreaField | 多行文本输入 | 文章内容、留言 |
BooleanField | 复选框 | 记住我、同意条款 |
SelectField | 下拉选择框 | 国家、省份选择 |
RadioField | 单选按钮 | 性别选择 |
FileField | 文件上传 | 上传头像、附件 |
DateField | 日期选择 | 生日、活动日期 |
九、表单样式美化
使用 Bootstrap 美化表单:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<form method="POST" class="container mt-5" style="max-width: 500px;">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.username.label(class="form-label") }}
{{ form.username(class="form-control") }}
{% if form.username.errors %}
<div class="invalid-feedback d-block">
{{ form.username.errors[0] }}
</div>
{% endif %}
</div>
<div class="mb-3">
{{ form.password.label(class="form-label") }}
{{ form.password(class="form-control") }}
{% if form.password.errors %}
<div class="invalid-feedback d-block">
{{ form.password.errors[0] }}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary">登录</button>
</form>
十、完整用户注册示例
from wtforms import Form, StringField, PasswordField, validators, SelectField, BooleanField
from wtforms.fields.html5 import EmailField, DateField
class RegistrationForm(Form):
username = StringField('用户名', [
validators.DataRequired('用户名不能为空'),
validators.Length(min=4, max=20)
])
email = EmailField('电子邮箱', [
validators.DataRequired('邮箱不能为空'),
validators.Email('请输入有效的邮箱地址')
])
password = PasswordField('密码', [
validators.DataRequired('密码不能为空'),
validators.EqualTo('confirm', message='两次密码必须一致')
])
confirm = PasswordField('确认密码')
gender = SelectField('性别', choices=[
('male', '男'),
('female', '女'),
('other', '其他')
])
birthdate = DateField('出生日期', format='%Y-%m-%d')
agree_tos = BooleanField('我同意服务条款', [
validators.DataRequired('必须同意条款才能注册')
])
对应的 HTML 模板:
<form method="POST" class="container mt-5" style="max-width: 500px;">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.username.label(class="form-label") }}
{{ form.username(class="form-control") }}
{% if form.username.errors %}
<div class="invalid-feedback d-block">
{{ form.username.errors[0] }}
</div>
{% endif %}
</div>
<div class="mb-3">
{{ form.email.label(class="form-label") }}
{{ form.email(class="form-control") }}
{% if form.email.errors %}
<div class="invalid-feedback d-block">
{{ form.email.errors[0] }}
</div>
{% endif %}
</div>
<div class="mb-3">
{{ form.password.label(class="form-label") }}
{{ form.password(class="form-control") }}
{% if form.password.errors %}
<div class="invalid-feedback d-block">
{{ form.password.errors[0] }}
</div>
{% endif %}
</div>
<div class="mb-3">
{{ form.confirm.label(class="form-label") }}
{{ form.confirm(class="form-control") }}
</div>
<div class="mb-3">
{{ form.gender.label(class="form-label") }}
{{ form.gender(class="form-select") }}
</div>
<div class="mb-3">
{{ form.birthdate.label(class="form-label") }}
{{ form.birthdate(class="form-control") }}
</div>
<div class="mb-3 form-check">
{{ form.agree_tos(class="form-check-input") }}
{{ form.agree_tos.label(class="form-check-label") }}
{% if form.agree_tos.errors %}
<div class="invalid-feedback d-block">
{{ form.agree_tos.errors[0] }}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary">注册</button>
</form>
十一、常见问题解答
Q1: 表单提交后为什么没有反应?
A: 检查以下几点:
- 确保表单的
method="POST"
- 确保路由设置了
methods=['GET', 'POST']
- 检查是否有
form.validate()
验证
Q2: 如何获取表单提交的数据?
A: 使用 form.field_name.data
,例如:
username = form.username.data
email = form.email.data
Q3: 如何设置表单的默认值?
A: 有两种方式:
- 在实例化表单时设置:
form = LoginForm(username="guest")
- 在模板中设置:
{{ form.username(value="guest") }}
Q4: 如何实现文件上传?
A: 使用 FileField
:
from wtforms import FileField
class UploadForm(Form):
file = FileField('上传文件')
然后在 Flask 中处理:
from werkzeug.utils import secure_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload():
form = UploadForm()
if form.validate_on_submit():
f = form.file.data
filename = secure_filename(f.filename)
f.save('uploads/' + filename)
return '文件上传成功'
return render_template('upload.html', form=form)
总结
WTForms 是一个非常实用的 Python 表单库,通过本教程你应该已经掌握了:
- 如何创建表单类
- 如何添加验证规则
- 如何在 HTML 中渲染表单
- 如何处理表单提交
- 如何美化表单样式
记住,表单处理是 Web 开发的基础,多加练习就能熟练掌握!