You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI更新含可空属性对象的最优方案 兼顾类型校验与灵活更新

解决方案

核心是利用Pydantic内置的字段传入状态跟踪能力,既保留类型校验能力,又能区分「字段未传入」和「主动设为null」两种场景,是FastAPI生态下的标准实现方案。

具体实现步骤

  1. 改造Pydantic更新模型,所有可更新字段均设为可选,默认值为None
  2. 调用模型的model_dump(Pydantic v2)或dict(Pydantic v1)方法时传入exclude_unset=True参数,自动过滤用户未主动传入的字段
  3. 用过滤后的字段批量更新目标对象即可

示例代码

from fastapi import Body, FastAPI
from typing import Optional, Literal
import dataclasses
from pydantic import BaseModel

app = FastAPI()

@dataclasses.dataclass
class User:
    name: str
    type: Optional[Literal['admin', 'guest']]

user = User('test_user', 'admin')

# 改造后的更新模型:所有字段可选,默认值为None
class UpdateUser(BaseModel):
    name: Optional[str] = None
    type: Optional[Literal['admin', 'guest']] = None

@app.put('/')
def put(update_user: UpdateUser):
    # 只保留用户主动传入的字段,未传入的自动过滤
    update_data = update_user.model_dump(exclude_unset=True)
    # 批量更新,未出现在update_data里的字段不会被修改
    for field, value in update_data.items():
        setattr(user, field, value)
    return user

方案优势

  • 完全保留Pydantic的类型校验能力:如果传入的字段值不符合类型定义(比如type传了super_admin),会自动返回422校验错误,不需要手动写校验逻辑
  • 完美区分两种场景:如果用户主动传了{"type": null},type字段会保留在update_data里,会被更新为None;如果用户没传type字段,该字段会被自动过滤,不会修改原有值
  • 符合REST API部分更新的标准语义,代码简洁易维护

兼容说明

如果使用Pydantic v1版本,只需将update_user.model_dump(exclude_unset=True)替换为update_user.dict(exclude_unset=True)即可,其余逻辑完全一致。


内容的提问来源于stack exchange,提问作者satodai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:09:02