Django中通过is_valid()捕获ValidationError并取errors字典返回结构化错误;DRF用Serializer的validate_field和validate方法抽离验证逻辑;Flask用WTForms,FastAPI用Pydantic模型校验;避免自建通用验证函数,应优先使用框架原生机制。

表单验证失败时 ValidationError 怎么捕获和处理
直接抛异常是默认行为,但生产环境里你通常不希望整个请求崩掉,而是返回结构化错误信息给前端。Django 的 Form 和 Serializer 都支持手动调用 is_valid(),而不是依赖视图自动触发验证。
-
is_valid()返回False时不抛异常,错误存在form.errors或serializer.errors中 - 别在
save()前漏掉is_valid()判断——否则save()可能静默失败或抛出底层异常 -
errors是字典,键是字段名,值是字符串列表(如{"email": ["Enter a valid email address."]}),前端渲染时注意嵌套结构
Django REST Framework 里怎么复用验证逻辑做 API 请求校验
DRF 的 Serializer 不只是序列化工具,它天然承担请求验证职责。关键不是“封装”,而是把验证逻辑从视图里抽出来,放到 Serializer 的 validate_<field> 方法或 validate() 中。
- 字段级验证用
validate_email(self, value),对象级用validate(self, data) - 不要在
validate()里写数据库查询——它在反序列化阶段执行,此时数据还没存库;查库逻辑放create()或视图里 - 如果多个接口共用同一套规则,把
Serializer单独定义成模块,而不是写在视图内部
自定义验证函数怎么接入 Flask 或 FastAPI 的请求体校验
Flask 没内置表单验证层,FastAPI 用 Pydantic 模型校验,二者路径不同但目标一致:让非法输入在进业务逻辑前就被拦截。
- Flask 里推荐用
WTForms+flask-wtf,表单类继承FlaskForm,验证靠form.validate_on_submit() - FastAPI 直接定义 Pydantic
BaseModel,字段类型和Field(..., min_length=1)就是验证规则;错误自动转成 422 响应,不用手写try/except - 别在 FastAPI 的
Body参数里传裸 dict——Pydantic 模型才能触发验证;传dict类型注解等于放弃所有校验
为什么封装“统一请求验证”容易翻车
所谓“通用验证封装”,比如写个 validate_request(data, rules) 函数,看似灵活,实际会快速变成维护黑洞。
- 规则描述难覆盖复杂逻辑(如“密码不能和用户名相同”需要两个字段联动,字典式 rules 很难表达)
- 错误提示无法绑定到具体字段——前端要显示“邮箱格式错误”,你却只返回“验证失败”
- 类型转换丢失:
int字段传了字符串,封装函数可能静默转成0,而原生框架会明确报"Not a valid integer."
真正省事的方式是用框架原生机制,而不是绕开它造轮子。验证逻辑分散在模型、序列化器或 Pydantic 模型里,比集中在一个万能函数里更可读、可测、可调试。

















