FastAPI中如何通过Pydantic复用模型公共字段?
问题描述
我正在使用FastAPI框架,基于Pydantic创建模型。目前有customerProfileShort和CustomerProfileLong两个模型,二者包含6个公共字段。我希望将这些公共字段统一定义在一处,以便在多个模型中复用,想了解当前采用单字段基类继承的方式是否可行,或是有更简便的实现方法?
以下是我尝试的代码示例(已修正语法错误):
from pydantic import BaseModel, Field from typing import Optional class First_name(BaseModel): first_name: str = Field(None, example="John") class Last_name(BaseModel): last_name: str = Field(None, example="Doe") class Actions_Count(BaseModel): actions_count: int = Field(None, example=131) class Event_performed(BaseModel): action_name: str = Field(None, example="check out") class Address(BaseModel): address: Optional[str] = Field(example="4849 William Terrace") class State(BaseModel): state: Optional[str] = Field(example="NC") class Country(BaseModel): country: Optional[str] = Field(example="US") class ShortCustomerProfile(Address,Actions_Count,Last_name,First_name): pass class State_Counts(State,Country): pass class Events_Performed_By_Customer(First_name,Last_name,Event_performed): pass
解决方案
单字段基类继承是否可行?
这种方式完全可行,Pydantic支持多继承,会自动合并所有基类的字段到子类中。但缺点很明显:每个字段单独建一个类,代码冗余度极高,维护起来麻烦,也不符合常规编码习惯。
更简便的实现方法
最常用高效的方式是按逻辑分组创建复用基类,要么把所有公共字段放在一个基类里,要么拆分成多个粒度适中的小基类,按需组合继承。
方式1:统一公共字段基类
如果customerProfileShort和CustomerProfileLong的6个公共字段是固定的,直接建一个基类即可:
from pydantic import BaseModel, Field from typing import Optional class CustomerBase(BaseModel): first_name: str = Field(None, example="John") last_name: str = Field(None, example="Doe") actions_count: int = Field(None, example=131) address: Optional[str] = Field(example="4849 William Terrace") state: Optional[str] = Field(example="NC") country: Optional[str] = Field(example="US") # 短信息模型直接继承基类 class CustomerProfileShort(CustomerBase): pass # 长信息模型在基类基础上添加额外字段 class CustomerProfileLong(CustomerBase): phone: Optional[str] = Field(example="123-456-7890") email: Optional[str] = Field(example="john.doe@example.com")
方式2:拆分逻辑组基类
如果还有其他模型需要复用部分字段(比如你代码中的State_Counts、Events_Performed_By_Customer),可以按逻辑拆分成小基类,灵活组合:
from pydantic import BaseModel, Field from typing import Optional # 身份名称字段组 class PersonName(BaseModel): first_name: str = Field(None, example="John") last_name: str = Field(None, example="Doe") # 地址信息字段组 class Location(BaseModel): address: Optional[str] = Field(example="4849 William Terrace") state: Optional[str] = Field(example="NC") country: Optional[str] = Field(example="US") # 行为统计字段组 class ActionStats(BaseModel): actions_count: int = Field(None, example=131) # 行为记录字段组 class ActionRecord(BaseModel): action_name: str = Field(None, example="check out") # 短信息模型:组合身份+地址+行为统计 class CustomerProfileShort(PersonName, Location, ActionStats): pass # 长信息模型:继承短信息模型并添加额外字段 class CustomerProfileLong(CustomerProfileShort): phone: Optional[str] = Field(example="123-456-7890") email: Optional[str] = Field(example="john.doe@example.com") # 你的其他模型 class State_Counts(Location): pass class Events_Performed_By_Customer(PersonName, ActionRecord): pass
额外注意点
- Pydantic多继承会自动合并字段,但要避免多个基类出现同名字段,否则会引发冲突。
- 字段的可选性、默认值、示例配置都会被子类继承,无需重复定义。
内容的提问来源于stack exchange,提问作者sandeep_a
相关产品推荐
相关产品推荐

