WTForms 超详细入门教程

本文章致力于让读者尽可能多的掌握 WTForms 的使用方法,希望每个初学者都能理解。

一、WTForms 是什么?

WTForms 是一个 Python 库,专门用来处理网页表单。它能帮你:

  1. 轻松创建表单
  2. 验证用户输入的数据
  3. 防止恶意数据提交
  4. 简化表单代码

二、安装 WTForms

打开命令行(Windows 的 cmd 或 Mac 的终端),输入:

pip install WTForms

安装完成后,就可以在 Python 中使用它了。

三、最简单的表单例子

让我们从一个最简单的登录表单开始:

from wtforms import Form, StringField, PasswordField

# 定义一个登录表单类
class LoginForm(Form):
    username = StringField('用户名')  # 用户名输入框
    password = PasswordField('密码')  # 密码输入框

代码解释:

  1. LoginForm(Form):创建一个表单类,继承自 Form
  2. StringField:文本输入框
  3. PasswordField:密码输入框(输入内容会显示为圆点)
  4. '用户名':字段的标签(显示在输入框前面的文字)

四、如何使用这个表单

在 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()

代码解释:

  1. request.form:获取用户提交的表单数据
  2. form.validate():检查表单数据是否有效
  3. 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>

代码解释:

  1. {{ form.hidden_tag() }}:自动生成隐藏的安全字段
  2. {{ form.username.label }}:显示"用户名"标签
  3. {{ form.username() }}:显示用户名输入框
  4. 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个字符')
    ])

验证器解释:

  1. DataRequired:字段不能为空
  2. Length:限制输入长度
  3. 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: 检查以下几点:

  1. 确保表单的 method="POST"
  2. 确保路由设置了 methods=['GET', 'POST']
  3. 检查是否有 form.validate() 验证

Q2: 如何获取表单提交的数据?

A: 使用 form.field_name.data,例如:

username = form.username.data
email = form.email.data

Q3: 如何设置表单的默认值?

A: 有两种方式:

  1. 在实例化表单时设置:
form = LoginForm(username="guest")
  1. 在模板中设置:
{{ 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 表单库,通过本教程你应该已经掌握了:

  1. 如何创建表单类
  2. 如何添加验证规则
  3. 如何在 HTML 中渲染表单
  4. 如何处理表单提交
  5. 如何美化表单样式

记住,表单处理是 Web 开发的基础,多加练习就能熟练掌握!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值