如何实现Pydantic模型驼峰与蛇形字段的双向序列化/反序列化?
解决Pydantic模型驼峰/蛇形命名双向序列化问题
核心思路
不用手动给每个字段加Field(alias="xxx"),而是通过自动别名生成器+序列化配置实现双向转换:
- 反序列化:API的驼峰数据自动映射到模型的蛇形字段
- 序列化:模型的蛇形字段自动转为驼峰格式输出
Pydantic v2 实现方案
1. 定义驼峰别名生成器
写一个函数把蛇形命名转成PascalCase格式:
from pydantic import BaseModel, ConfigDict def snake_to_pascal(snake_str: str) -> str: components = snake_str.split('_') return ''.join(x.capitalize() for x in components)
2. 配置模型参数
在模型的model_config里指定别名生成规则,同时开启双向兼容的配置:
class Position(BaseModel): model_config = ConfigDict( alias_generator=snake_to_pascal, populate_by_name=True, # 允许通过字段名或别名反序列化 ser_json_use_alias=True # 序列化JSON时自动使用驼峰别名 ) latitude: float longitude: float altitude: float | None = None
3. 测试双向转换
# 反序列化:API驼峰数据转模型实例 api_data = {"Latitude": 39.9042, "Longitude": 116.4074, "Altitude": 50} position = Position(**api_data) print(position.latitude) # 输出: 39.9042 # 序列化:模型实例转驼峰格式API数据 api_output = position.model_dump_json() print(api_output) # 输出: {"Latitude":39.9042,"Longitude":116.4074,"Altitude":50}
Pydantic v1 实现方案
如果仍在使用v1版本,配置方式略有差异:
from pydantic import BaseModel from pydantic.utils import camelize class Position(BaseModel): class Config: alias_generator = camelize allow_population_by_field_name = True # 兼容字段名/别名反序列化 latitude: float longitude: float altitude: float | None = None # 测试 api_data = {"Latitude": 39.9042, "Longitude": 116.4074} position = Position(**api_data) print(position.json(by_alias=True)) # 序列化时需指定by_alias=True # 输出: {"Latitude":39.9042,"Longitude":116.4074,"Altitude":null}
关键注意事项
- 不要手动给字段加
alias参数,否则会覆盖自动生成的别名,导致双向转换失效 - 若有特殊字段需要自定义别名,可单独用
Field(alias="CustomName"),但需确保和自动生成规则不冲突 - Pydantic v2中
ser_json_use_alias=True是序列化用别名的核心;v1必须在json()方法中显式指定by_alias=True
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

