Pydantic反向继承结构实现需求及现存问题
解决方案:从Pydantic DB模型反向继承并排除字段
方法一:自定义装饰器实现字段隐藏
你想要的@decorator(hide={...})方案完全可行,通过动态创建模型可以彻底排除指定字段,实现和手动定义请求模型一致的效果。以下是具体实现:
from pydantic import BaseModel, create_model def hide_fields(hide: set[str]): def decorator(model_cls): # 筛选保留字段,排除hide集合中的字段 retained_fields = {} for field_name, field in model_cls.__fields__.items(): if field_name not in hide: # 保留字段的注解和原始配置 retained_fields[field_name] = (field.annotation, field) # 动态生成新模型,继承自原DB模型,仅保留筛选后的字段 filtered_model = create_model( model_cls.__name__, __base__=model_cls, **retained_fields ) # 复制原模型的配置 filtered_model.model_config = model_cls.model_config.copy() return filtered_model return decorator
使用示例
# 定义包含所有字段的MongoDB模型 class DBTask(BaseModel): task_id: str task_type: int username: str firstname: str lastname: str address: str email: str phone: str # 通过装饰器生成请求模型,排除不需要的字段 @hide_fields(hide={"address", "email", "phone"}) class ReqUserCreation(DBTask): pass @hide_fields(hide={"username", "firstname", "lastname"}) class ReqUserInfo(DBTask): pass
效果验证
model_validate时仅需提供保留字段,无需传入被排除字段- FastAPI自动生成的接口文档中只会显示保留字段
- 序列化时不会包含被排除字段,完全等同于手动定义的请求模型
方法二:直接用create_model动态生成请求模型
如果不需要装饰器语法,也可以直接调用create_model生成请求模型,避免重复代码:
from pydantic import create_model # 生成用户创建请求模型 ReqUserCreation = create_model( "ReqUserCreation", __base__=DBTask, **{name: (field.annotation, field) for name, field in DBTask.__fields__.items() if name not in {"address", "email", "phone"}} ) # 生成用户信息请求模型 ReqUserInfo = create_model( "ReqUserInfo", __base__=DBTask, **{name: (field.annotation, field) for name, field in DBTask.__fields__.items() if name not in {"username", "firstname", "lastname"}} )
关键说明
- 两种方案均通过动态创建新模型彻底移除指定字段,避免了继承导致的字段残留问题
- 生成的模型在验证、Schema生成、序列化等行为上,和手动定义的请求模型完全一致
- 装饰器方案更贴合你期望的简洁语法,适合在项目中统一复用
内容的提问来源于stack exchange,提问作者AliSot 2000
相关产品推荐
相关产品推荐

