记录在 Flask 项目中使用 WTForms 自定义表单校验器的方法与注意事项。
一、使用场景
- 默认的 WTForms 校验器不足以满足业务需求
- 需要跨字段校验(如密码与确认密码一致)
- 需要访问数据库进行校验(如用户名是否已存在)
二、自定义单字段校验器
WTForms 允许在表单类中定义 validate_<字段名>
方法进行校验。
from wtforms import Form, StringField, ValidationError
class MyForm(Form):
username = StringField('用户名')
def validate_username(self, field):
if 'admin' in field.data.lower():
raise ValidationError('用户名不能包含 admin')
三、通用函数式校验器
自定义函数式校验器可复用在多个表单字段中。
from wtforms import ValidationError
def no_special_chars(form, field):
import re
if re.search(r'[^a-zA-Z0-9]', field.data):
raise ValidationError('不能包含特殊字符')
使用:
username = StringField('用户名', validators=[no_special_chars])
四、跨字段校验
需要同时访问多个字段时,可在表单类中重写 validate
方法。
class RegisterForm(Form):
password = StringField('密码')
confirm_password = StringField('确认密码')
def validate(self):
rv = super().validate()
if not rv:
return False
if self.password.data != self.confirm_password.data:
self.confirm_password.errors.append('两次密码不一致')
return False
return True
五、结合数据库校验
from models import User
def unique_username(form, field):
if User.query.filter_by(username=field.data).first():
raise ValidationError('用户名已存在')
六、小结
validate_<字段名>
适合字段独立校验- 函数式校验器便于复用
- 跨字段校验需在
validate
方法中处理 - 涉及数据库时要考虑性能与并发情况