title: Pydantic字段级校验:解锁@validator的12种应用

date: 2025/3/23

updated: 2025/3/23

author: cmdragon

excerpt:

Pydantic校验系统支持通过pre验证器实现原始数据预处理,在类型转换前完成字符清洗等操作。格式验证涵盖正则表达式匹配与枚举值约束,确保护照编号等字段符合规范。动态校验机制处理跨字段依赖关系及环境感知验证,根据运行时条件调整校验规则。安全校验模块防御SQL注入与XSS攻击,采用字符过滤和HTML转义策略。高级转换功能实现地址标准化、敏感信息加密等数据处理,企业级实践包含分布式ID验证与金融精度控制。校验错误处理需关注类型一致性及验证顺序,遵循"早失败"原则构建模块化校验规则库,推荐使用参数化查询等最佳安全实践。

categories:

  • 后端开发
  • FastAPI

tags:

  • Pydantic字段校验
  • @validator高级应用
  • 数据验证模式
  • 防御式编程
  • 校验器组合
  • 动态依赖验证
  • 企业级数据清洗

扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

探索数千个预构建的 AI 应用,开启你的下一个伟大创意


第一章:基础校验模式

1.1 类型强制转换

from pydantic import BaseModel, validator

class CurrencyConverter(BaseModel):
amount: str @validator("amount", pre=True)
def string_to_float(cls, v):
return float(v.strip("$")) # 自动转换 "$100.5" → 100.5
print(CurrencyConverter(amount="$100.5").amount)

pre验证器特性

  • 在类型转换前执行
  • 支持原始数据清洗
  • 可处理非结构化输入

第二章:格式验证

2.1 正则表达式验证

import re

class IdentityForm(BaseModel):
passport: str @validator("passport")
def validate_passport(cls, v):
if not re.match(r"^[A-PR-WY][1-9]\d\s?\d{4}[A-Z]$", v):
raise ValueError("护照号码格式错误")
return v.upper().replace(" ", "")

2.2 枚举值约束

from enum import Enum

class Department(Enum):
HR = 1
IT = 2 class Employee(BaseModel):
dept: int @validator("dept")
def check_department(cls, v):
return Department(v).name # 自动转换数字为枚举名称

第三章:动态校验

3.1 跨字段依赖验证

class OrderForm(BaseModel):
product_type: str
weight: float @validator("weight")
def check_weight(cls, v, values):
if values.get("product_type") == "fragile" and v > 10:
raise ValueError("易碎品不得超过10kg")
return v

3.2 环境感知校验

import os

class EnvAwareValidator(BaseModel):
api_key: str @validator("api_key")
def check_key_format(cls, v):
env = os.getenv("APP_ENV", "dev")
if env == "prod" and len(v) < 32:
raise ValueError("生产环境密钥强度不足")
return v

第四章:安全校验

4.1 SQL注入防御

class QuerySafe(BaseModel):
search_term: str @validator("search_term")
def sanitize_input(cls, v):
forbidden = ["'", ";", "--", "/*"]
if any(c in v for c in forbidden):
raise ValueError("检测到危险字符")
return v.replace("%", "\\%")

4.2 XSS攻击过滤

from html import escape

class CommentForm(BaseModel):
content: str @validator("content")
def sanitize_html(cls, v):
return escape(v).replace("\n", "<br>")

第五章:高级转换

5.1 数据归一化

class AddressNormalizer(BaseModel):
street: str @validator("street")
def standardize_address(cls, v):
replacements = {
"St.": "Street",
"Ave": "Avenue"
}
for k, v in replacements.items():
v = v.replace(k, v)
return v.title()

5.2 加密字段处理

from cryptography.fernet import Fernet

class SecureData(BaseModel):
secret: str @validator("secret")
def encrypt_value(cls, v):
key = Fernet.generate_key()
return Fernet(key).encrypt(v.encode())

第六章:企业级实践

6.1 分布式ID验证

import snowflake

class SnowflakeValidator(BaseModel):
object_id: str @validator("object_id")
def validate_snowflake(cls, v):
try:
snowflake.deconstruct(v)
return v
except Exception:
raise ValueError("非法分布式ID格式")

6.2 金融精度控制

from decimal import Decimal, ROUND_HALF_UP

class FinancialModel(BaseModel):
amount: float @validator("amount")
def monetary_precision(cls, v):
return Decimal(str(v)).quantize(
Decimal("0.00"),
rounding=ROUND_HALF_UP
)

课后Quiz

Q1:pre验证器的执行时机是?

A) 类型转换后

B) 类型转换前

C) 最终验证阶段

Q2:防御SQL注入的最佳方法是?

  1. 字符串替换
  2. 参数化查询
  3. 正则过滤

Q3:处理多字段依赖应使用?

  • root_validator
  • 多个字段级校验器
  • 自定义__init__方法

错误解决方案速查表

错误信息 原因分析 解决方案
ValidationError: value is not a valid integer 类型转换前未清洗数据 添加pre=True验证器
ValueError: 检测到危险字符 SQL注入防御生效 使用参数化查询替代直接拼接
AssertionError: 校验顺序错误 依赖字段未优先验证 调整字段定义顺序
TypeError: 校验器返回类型错误 验证器返回值与声明类型不符 检查验证器逻辑

架构原则:字段校验应遵循"早失败"原则,在数据入口处完成所有验证。建议建立企业级校验规则库,通过装饰器模式实现校验逻辑的模块化管理。

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:

往期文章归档:

Pydantic字段级校验:解锁@validator的12种应用的更多相关文章

  1. ETL应用:使用shell实现文件级校验的方法

    BI应用中,对接口规范性约束很重要,接口文件提供需要配套提供该文件的校验文件,校验文件格式如下: 序号 信息内容 数据类型及长度 说明 1 接口数据文件名称 CHAR(50) 2 文件的大小(字节数) ...

  2. SQL 建立多个字段唯一性校验

    由于在做压力测试,同一时间占用的问题. 两个用户同时下同一时间的订单,需要增加校验,第一个能保存的用户保存,第二个就不能让保存了. 问题是通过代码,怎么都做不到毫秒级校验,所以解决办法就只能是通过数据 ...

  3. Vue 两个字段联合校验典型例子--修改密码

    1.前言   本文是前文<Vue Element-ui表单校验规则,你掌握了哪些?>针对多字段联合校验的典型应用.   在修改密码时,一般需要确认两次密码一致,涉及2个属性字段.类似的涉及 ...

  4. Java-Runoob-高级教程-实例-方法:12. Java 实例 – Enum(枚举)构造函数及方法的使用-um

    ylbtech-Java-Runoob-高级教程-实例-方法:12. Java 实例 – Enum(枚举)构造函数及方法的使用 1.返回顶部 1. Java 实例 - Enum(枚举)构造函数及方法的 ...

  5. Java-Runoob-高级教程-实例-数组:12. Java 实例 – 数组差集

    ylbtech-Java-Runoob-高级教程-实例-数组:12. Java 实例 – 数组差集 1.返回顶部 1. Java 实例 - 数组差集  Java 实例 以下实例演示了如何使用 remo ...

  6. Java-Runoob-高级教程-实例-字符串:12. Java 实例 - 字符串优化

    ylbtech-Java-Runoob-高级教程-实例-字符串:12. Java 实例 - 字符串优化 1.返回顶部 1. Java 实例 - 字符串优化  Java 实例 以下实例演示了通过 Str ...

  7. Oracle 11g对依赖的推断达到字段级

    在Oracle 10g下,推断依赖性仅仅达到了对象级.也就是说存储过程訪问的对象一旦发生了变化.那么Oracle就会将存储过程置为INVALID状态.所以在为表做了DDL操作后.须要把存储过程又一次进 ...

  8. SNF快速开发平台2019-权限管理模型-记录级-字段级权限实践

    1.1.1  字段级权限 字段级权限适用于对不同人的能否查看或录入不同表不同字段的权限控制. 是否启用字段级权限配置 不启用字段级权限后,[用户权限管理]程序[字段级权限]按钮会隐藏,导致无法给管理其 ...

  9. MongoDB 4.2新特性:分布式事务、字段级加密、通配符索引、物化视图

    MongoDB 4.2已经发布,我们来看看它增加了哪些新特性?分布式事务?数据库加密?通配符索引? 在2019年MongoDB World大会上,CTO Eliot Horowitz介绍了MongoD ...

  10. Oval框架如何校验枚举类型的一种思路

    前言: Oval校验框架被广泛集成于各类接口参数校验中, 其方便的注解语法, 易读性和扩展性. 几乎成了java后端服务代码的标配. 有人会很疑惑, 都已经是枚举类型了, 还需要校验吗? 其实这边更确 ...

随机推荐

  1. 前端学习openLayers配合vue3(圆形形状的绘制)

    上节课我们学了加载了矢量图片,这节我们来学绘制圆形 关键代码,第一段呢是设置圆点的操作,第二步是点击地图获取地图位置来设置圆点,ol还有很多类,各种形状的 //设置圆点 // let anchorLa ...

  2. nginx平台初探-5

    nginx的请求处理阶段 (90%)   接收请求流程 (99%)   http请求格式简介 (99%) 首先介绍一下rfc2616中定义的http请求基本格式:   Request = Reques ...

  3. 容器、容器云和容器化PaaS平台之间到底是什么关系?

    本文分享自天翼云开发者社区<容器.容器云和容器化PaaS平台之间到底是什么关系?>,作者:s****n 一直都有很多人迷惑于容器应该属于 IaaS 或是 PaaS 层,也搞不清楚容器云到底 ...

  4. SqlServer性能检测之Sql语句排查

    很多时候,我们在用SQL语句查询数据时,难免会漏掉对SQL语句性能的考虑,所以有时就会造成SqlServer服务占用过高的问题,为了大致排查是哪些SQL语句造成的问题,我们可以通过如下SQL查询出最近 ...

  5. Esp32s3(立创实战派)移植LVGL

    Esp32s3(立创实战派)移植LVGL 移植: 使用软件EEZ studio 创建工程选择带EEZ Flow的,可以使用该软件更便捷的功能 根据屏幕像素调整画布为320*240 复制ui文件至工程 ...

  6. el-radio-group初始化默认值后点击无法切换问题/vue中设置表单对象属性页面不同步问题

    <el-radio-group v-model="ruleForm.type"> <el-radio :label="1">方案一< ...

  7. xbox商店访问、下载速度慢,如何提升下载速度?

    Xbox下载速度慢可能是由于多种原因,例如网络连接问题.微软服务器问题等.以下是一些可以尝试的方法来提升Xbox的下载速度: 更改网络设置:以WIN11举例:鼠标右键点电脑桌面右下角的网络图标,选择& ...

  8. Kubernetes - [03] 安装部署

    Kubeadm 部署k8s集群 一.准备工作 1.1.组件 组件:Harbor(私有Docker Hub).Router 服务器操作系统:Centos7 +(内核3.0+,最好内核4.40+) 1.2 ...

  9. Jenkins - [01] 概述

    "持续集成并不能消除Bug,而是让它们非常容易发现和改正." -- Martin Fowler 一.概述 1.1.持续集成(CI)   持续集成(Continuous integr ...

  10. OERV兴趣探索:模拟器移植

      最近看了很多开源项目,主要都集中在模拟器方面,我指的是游戏模拟器比如GameBoy或者PlayStation这一类.现在想玩这系列的游戏可以在手机或者电脑下载相应的模拟器,并且获取对应的ROM文件 ...