如何用Pydantic模型处理带固定格式的动态字段名?
处理动态键的Pydantic模型设计
方案一:将动态键转换为子模型列表
完全可以实现你想要的结构,通过Pydantic的预处理验证器,把符合response_code_count/xxx格式的键值对转换成子模型列表。
Pydantic v2 实现代码
from pydantic import BaseModel, model_validator from typing import List, Dict, Any class ResponseCodeCount(BaseModel): response_code: str count: int class Response(BaseModel): response_code_counts: List[ResponseCodeCount] some_other_field: str @model_validator(mode='before') def process_response_code_counts(cls, data: Dict[str, Any]) -> Dict[str, Any]: code_counts = [] remaining_data = {} for key, value in data.items(): if key.startswith('response_code_count/'): # 拆分出响应码部分 response_code = key.split('/', 1)[1] code_counts.append({'response_code': response_code, 'count': value}) else: remaining_data[key] = value # 将转换后的列表加入待解析数据 remaining_data['response_code_counts'] = code_counts return remaining_data # 测试示例 input_data = { "response_code_count/R1": 23, "response_code_count/PX1": 58, "some_other_field": "some_other_value" } response = Response(**input_data) print(response.response_code_counts) # 输出: [ResponseCodeCount(response_code='R1', count=23), ResponseCodeCount(response_code='PX1', count=58)] print(response.some_other_field) # 输出: some_other_value
Pydantic v1 实现代码
如果使用Pydantic v1,将model_validator替换为root_validator即可:
from pydantic import BaseModel, root_validator from typing import List, Dict, Any class ResponseCodeCount(BaseModel): response_code: str count: int class Response(BaseModel): response_code_counts: List[ResponseCodeCount] some_other_field: str @root_validator(pre=True) def process_response_code_counts(cls, data: Dict[str, Any]) -> Dict[str, Any]: code_counts = [] remaining_data = {} for key, value in data.items(): if key.startswith('response_code_count/'): response_code = key.split('/', 1)[1] code_counts.append({'response_code': response_code, 'count': value}) else: remaining_data[key] = value remaining_data['response_code_counts'] = code_counts return remaining_data
方案二:直接验证并保留动态键结构
如果不需要转换为列表,只是要验证动态键的格式并直接访问,可以使用带正则验证的字典字段:
Pydantic v2 实现代码
from pydantic import BaseModel from typing import Dict from annotated_types import Pattern class Response(BaseModel): # 强制验证键必须符合 `response_code_count/[字母数字]` 的格式 response_code_counts: Dict[Pattern[r'^response_code_count/[A-Z0-9]+$'], int] some_other_field: str # 测试示例 input_data = { "response_code_count/R1": 23, "response_code_count/PX1": 58, "some_other_field": "some_other_value" } response = Response(**input_data) # 直接通过原始键访问值 print(response.response_code_counts['response_code_count/R1']) # 输出: 23
这种方式适合需要保留原始键结构的场景,同时确保所有response_code_count相关的键都符合指定格式。
内容的提问来源于stack exchange,提问作者Jossy
相关产品推荐
相关产品推荐

