如何为FastAPI嵌套模型单独设置exclude_unset导出行为?
问题描述
假设我有如下基于Pydantic的FastAPI模型:
class Filter(BaseModel, extra=Extra.forbid): expression: str | None kind: str | None ... class Configuration(BaseModel): filter: Filter | None = {} ....
默认情况下,当未给filter传任何值时,模型导出的结果是这样的:
{ "filter": { "expression": null, "kind": null, ... }, ... }
但我想要的导出结果是:
{ "filter": {}, ... }
现在需要实现:让这个嵌套的Filter模型在导出时始终应用exclude_unset行为,且在复杂模型中仅针对部分嵌套模型排除未设置字段,其他模型保留原有字段。已知全局的exclude_unset和response_model_exclude_unset会影响整个模型,因此需要单独控制单个嵌套模型的序列化行为。
解决方案
方法一:给嵌套模型强制添加序列化规则
直接修改Filter模型,让它在序列化时默认启用exclude_unset=True,这样不管父模型怎么设置,这个嵌套模型自身都会排除未设置的字段。
修改后的Filter模型代码:
from pydantic import BaseModel, Extra class Filter(BaseModel, extra=Extra.forbid): expression: str | None kind: str | None ... def dict(self, **kwargs): # 强制转字典时排除未设置字段 kwargs.setdefault('exclude_unset', True) return super().dict(**kwargs) def json(self, **kwargs): # 强制转JSON时应用同样规则 kwargs.setdefault('exclude_unset', True) return super().json(**kwargs)
只要是Filter的实例,序列化后都会自动去掉未设置的字段,空实例就会输出{}。
方法二:在父模型中单独处理目标字段
如果不想改动Filter模型的全局行为,可以在父模型Configuration里给filter字段添加序列化器,单独对它应用exclude_unset规则。
示例代码:
from pydantic import BaseModel, Extra, field_serializer class Filter(BaseModel, extra=Extra.forbid): expression: str | None kind: str | None ... class Configuration(BaseModel): filter: Filter | None = {} .... @field_serializer('filter') def serialize_filter(self, value: Filter | None) -> dict | None: if not value: return {} # 仅对当前filter字段应用exclude_unset=True return value.dict(exclude_unset=True)
这种方式只会在Configuration模型里生效,其他地方使用Filter模型时不受影响。
方法三:FastAPI接口中手动构造响应
如果只是在某个接口的响应里需要这个效果,可以在返回数据时手动处理filter字段的序列化:
from fastapi import FastAPI app = FastAPI() @app.get("/config", response_model=Configuration) def get_config(): config = Configuration() # 先把整个模型转成字典,再替换filter字段的序列化结果 resp_data = config.dict() resp_data['filter'] = config.filter.dict(exclude_unset=True) if config.filter else {} return resp_data
这种方法适合临时的局部场景,无需修改模型定义。
内容的提问来源于stack exchange,提问作者Matt Sanders
相关产品推荐
相关产品推荐

