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

打印 上一主题 下一主题

主题 994|帖子 994|积分 2982

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 类型欺压转换
  1. from pydantic import BaseModel, validator
  2. class CurrencyConverter(BaseModel):
  3.     amount: str
  4.     @validator("amount", pre=True)
  5.     def string_to_float(cls, v):
  6.         return float(v.strip("$"))
  7. # 自动转换 "$100.5" → 100.5
  8. print(CurrencyConverter(amount="$100.5").amount)  
复制代码
pre验证器特性

  • 在类型转换前执行
  • 支持原始数据洗濯
  • 可处理非结构化输入
第二章:格式验证

2.1 正则表达式验证
  1. import re
  2. class IdentityForm(BaseModel):
  3.     passport: str
  4.     @validator("passport")
  5.     def validate_passport(cls, v):
  6.         if not re.match(r"^[A-PR-WY][1-9]\d\s?\d{4}[A-Z]$", v):
  7.             raise ValueError("护照号码格式错误")
  8.         return v.upper().replace(" ", "")
复制代码
2.2 枚举值约束
  1. from enum import Enum
  2. class Department(Enum):
  3.     HR = 1
  4.     IT = 2
  5. class Employee(BaseModel):
  6.     dept: int
  7.     @validator("dept")
  8.     def check_department(cls, v):
  9.         return Department(v).name  # 自动转换数字为枚举名称
复制代码
第三章:动态校验

3.1 跨字段依赖验证
  1. class OrderForm(BaseModel):
  2.     product_type: str
  3.     weight: float
  4.     @validator("weight")
  5.     def check_weight(cls, v, values):
  6.         if values.get("product_type") == "fragile" and v > 10:
  7.             raise ValueError("易碎品不得超过10kg")
  8.         return v
复制代码
3.2 环境感知校验
  1. import os
  2. class EnvAwareValidator(BaseModel):
  3.     api_key: str
  4.     @validator("api_key")
  5.     def check_key_format(cls, v):
  6.         env = os.getenv("APP_ENV", "dev")
  7.         if env == "prod" and len(v) < 32:
  8.             raise ValueError("生产环境密钥强度不足")
  9.         return v
复制代码
第四章:安全校验

4.1 SQL注入防御
  1. class QuerySafe(BaseModel):
  2.     search_term: str
  3.     @validator("search_term")
  4.     def sanitize_input(cls, v):
  5.         forbidden = ["'", ";", "--", "/*"]
  6.         if any(c in v for c in forbidden):
  7.             raise ValueError("检测到危险字符")
  8.         return v.replace("%", "\\%")
复制代码
4.2 XSS攻击过滤
  1. from html import escape
  2. class CommentForm(BaseModel):
  3.     content: str
  4.     @validator("content")
  5.     def sanitize_html(cls, v):
  6.         return escape(v).replace("\n", "
  7. ")
复制代码
第五章:高级转换

5.1 数据归一化
  1. class AddressNormalizer(BaseModel):
  2.     street: str
  3.     @validator("street")
  4.     def standardize_address(cls, v):
  5.         replacements = {
  6.             "St.": "Street",
  7.             "Ave": "Avenue"
  8.         }
  9.         for k, v in replacements.items():
  10.             v = v.replace(k, v)
  11.         return v.title()
复制代码
5.2 加密字段处理
  1. from cryptography.fernet import Fernet
  2. class SecureData(BaseModel):
  3.     secret: str
  4.     @validator("secret")
  5.     def encrypt_value(cls, v):
  6.         key = Fernet.generate_key()
  7.         return Fernet(key).encrypt(v.encode())
复制代码
第六章:企业级实践

6.1 分布式ID验证
  1. import snowflake
  2. class SnowflakeValidator(BaseModel):
  3.     object_id: str
  4.     @validator("object_id")
  5.     def validate_snowflake(cls, v):
  6.         try:
  7.             snowflake.deconstruct(v)
  8.             return v
  9.         except Exception:
  10.             raise ValueError("非法分布式ID格式")
复制代码
6.2 金融精度控制
  1. from decimal import Decimal, ROUND_HALF_UP
  2. class FinancialModel(BaseModel):
  3.     amount: float
  4.     @validator("amount")
  5.     def monetary_precision(cls, v):
  6.         return Decimal(str(v)).quantize(
  7.             Decimal("0.00"),
  8.             rounding=ROUND_HALF_UP
  9.         )
复制代码
课后Quiz

Q1:pre验证器的执行时机是?
A) 类型转换后
B) 类型转换前
C) 终极验证阶段
Q2:防御SQL注入的最佳方法是?

  • 字符串替换
  • 参数化查询
  • 正则过滤
Q3:处理多字段依赖应使用?

  • root_validator
  • 多个字段级校验器
  • 自定义__init__方法
错误解决方案速查表

错误信息原因分析解决方案ValidationError: value is not a valid integer类型转换前未洗濯数据添加pre=True验证器ValueError: 检测到危险字符SQL注入防御收效使用参数化查询替代直接拼接AssertionError: 校验序次错误依赖字段未优先验证调解字段定义序次TypeError: 校验器返回类型错误验证器返回值与声明类型不符检查验证器逻辑架构原则:字段校验应遵照"早失败"原则,在数据入口处完成全部验证。建议建立企业级校验规则库,通过装饰器模式实现校验逻辑的模块化管理。
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完备的文章:
往期文章归档:

<ul>Pydantic配置继承抽象基类模式 | cmdragon's Blog
Pydantic多态模型:用辨别器构建类型安全的API接口 | cmdragon's Blog
FastAPI性能优化指南:参数解析与惰性加载 | cmdragon's Blog
FastAPI依赖注入:参数共享与逻辑复用 | cmdragon's Blog
FastAPI安全防护指南:构建坚不可摧的参数处理体系 | cmdragon's Blog
FastAPI复杂查询终极指南:告别if-else的当代化过滤架构 | cmdragon's Blog
FastAPI 核心机制:分页参数的实现与最佳实践 | cmdragon's Blog
<a href="https://blog.cmdragon.cn/posts/615a966b68d9/" target="_blank" rel="noopener nofollow">FastAPI 错误处理与自定义错误消息完全指南:构建健壮的 API 应用
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表