Flask校验

WTForms 是一个 Python 库,用于处理和验证 Web 表单。它提供了很多功能来简化表单处理,包括字段类型、验证器、错误消息等。在 WTForms 中,validate 机制是用于确保表单数据满足特定条件的关键部分。

1.验证器(Validators)

WTForms 提供了多种内置的验证器,如 DataRequired, Length, Email, EqualTo 等,这些可以被添加到表单字段上以执行特定的验证规则。例如:

python 复制代码
from wtforms import StringField, validators

class LoginForm(Form):
    username = StringField('Username', [validators.DataRequired()])
    password = PasswordField('Password', [
        validators.DataRequired(),
        validators.Length(min=8)
    ])

在这个例子中,DataRequired 确保字段不为空,Length 则确保密码长度至少为 8。

2.自定义验证器

你也可以定义自己的验证函数,并将其作为验证器使用。这个函数应该接收表单实例和字段实例作为参数,并在验证失败时抛出 ValidationError 异常。例如:

python 复制代码
from wtforms import StringField, ValidationError
from wtforms.validators import StopValidation

def unique_username(form, field):
    if User.query.filter_by(username=field.data).first():
        raise ValidationError('Username already exists.')

class RegistrationForm(Form):
    username = StringField('Username', [unique_username])

在这个例子中,unique_username 函数检查数据库中是否已存在相同的用户名,如果存在,则抛出 ValidationError。

3.全局验证

除了字段级别的验证之外,你还可以定义全局验证方法,在表单类中定义以 validate_ 开头的方法,后面跟着字段名,这会触发对整个表单的验证。这种方法通常用于需要跨多个字段的复杂验证逻辑。例如:

python 复制代码
class RegistrationForm(Form):
    username = StringField('Username')
    password = PasswordField('Password')
    confirm_password = PasswordField('Confirm Password')

    def validate_confirm_password(self, field):
        if field.data != self.password.data:
            raise ValidationError('Passwords do not match.')

这里,validate_confirm_password 方法确保用户输入的密码与其确认密码相同。

4. 使用多个验证器

你可以将多个验证器应用于同一个字段,例如,确保电子邮件格式正确并且非空:

python 复制代码
from wtforms import StringField, EmailField
from wtforms.validators import DataRequired, Email

class ContactForm(Form):
    email = EmailField('Email', validators=[DataRequired(), Email()])

5. 自定义验证器示例 - 检查年龄

假设你想要验证用户年龄必须大于18岁:

python 复制代码
from datetime import date

def is_adult(form, field):
    today = date.today()
    age = today.year - field.data.year - ((today.month, today.day) < (field.data.month, field.data.day))
    if age < 18:
        raise ValidationError('You must be at least 18 years old.')

class RegistrationForm(Form):
    birth_date = DateField('Birth Date', validators=[is_adult])

6. 验证唯一性 - 检查用户名或邮箱是否已被注册

在数据库中检查某个值是否唯一:

python 复制代码
from myapp.models import User

def unique_username(form, field):
    if User.query.filter_by(username=field.data).first() is not None:
        raise ValidationError('Username already exists.')

def unique_email(form, field):
    if User.query.filter_by(email=field.data).first() is not None:
        raise ValidationError('Email already exists.')

class RegistrationForm(Form):
    username = StringField('Username', validators=[unique_username])
    email = StringField('Email', validators=[unique_email])

7. 自定义错误消息

你可以覆盖默认的错误消息,使其更加友好或具体:

python 复制代码
class ContactForm(Form):
    subject = StringField('Subject', validators=[DataRequired(message='Please enter a subject.')])
    message = TextAreaField('Message', validators=[Length(max=200, message='Your message is too long.')])

下面是一个使用 验证器的用户注册完整例子:

python 复制代码
from wtforms import Form, StringField, PasswordField, validators

class RegistrationForm(Form):
    username = StringField('Username', [validators.Length(min=4, max=25)])
    email = StringField('Email Address', [validators.Length(min=6, max=35),
                                          validators.Email()])
    password = PasswordField('New Password', [
        validators.DataRequired(),
        validators.EqualTo('confirm', message='Passwords must match')
    ])
    confirm = PasswordField('Repeat Password')

# 使用表单
form = RegistrationForm(request.form)

if request.method == 'POST' and form.validate():
    # 如果表单验证成功,可以进一步处理数据,比如保存到数据库
    user = User(username=form.username.data, email=form.email.data,
                password=generate_password_hash(form.password.data))
    db.session.add(user)
    db.session.commit()
else:
    # 如果表单验证失败,显示错误消息
    flash_errors(form)

在这个例子中,RegistrationForm 包含了 username, email, password, 和 confirm 字段。password 字段使用了 EqualTo 验证器,它会检查 password 和 confirm 字段的值是否相同。如果这两个字段的值不同,EqualTo 验证器会抛出一个 ValidationError,并附带错误消息 "Passwords must match"。

EqualTo 验证器的第一个参数是要与当前字段比较的另一个字段的名称。在上面的例子中,password 字段通过 EqualTo('confirm') 与 confirm 字段进行比较。

如果在实际应用中遇到问题,或者需要进一步定制验证逻辑,你也可以自定义验证函数来配合 EqualTo 或其他验证器一起使用。

相关推荐
我命由我12345几秒前
Python 实用操作 - 文件操作(打开与关闭文件、读取文件、文件写入)
java·开发语言·前端·javascript·数据库·python·java-ee
青少儿编程课堂6 分钟前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:倍增法求最近公共祖先LCA解析
c++·python·算法·bfs·信息学竞赛
SelectDB22 分钟前
Apache Doris 与 SelectDB 是什么关系?从开源技术到面向 Agent 的极速分析数据库
大数据·数据库·数据分析
atwednesday27 分钟前
一文理解python中的task,协程,woker
python
VimorphTech39 分钟前
文本已经改了,旧的音频生成结果还能回写吗?
java·数据库·mybatis
SelectDB40 分钟前
存算分离冷查询提速 7.5 倍!Apache Doris 4.2 Peer Read 实现跨计算组缓存复用
大数据·数据库·数据分析
盛世宏博智慧档案1 小时前
一站式智慧档案解决方案,如何实现防火防盗漏水多维度安全监测实践
服务器·网络·数据库
数据库小学妹1 小时前
MySQL磁盘IO瓶颈:iostat与刷脏fsync
数据库·mysql·性能优化
用户0332126663671 小时前
使用 Python 在 Excel 中添加与删除筛选器
python·excel
1M551 小时前
AI应用后端工程(03):回答输出一半就断了:AI 流式接口如何定义成功与失败?
python·面试·职场和发展·计算机专业·agent开发