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

FastAPI中请求体无法获取/发送_id字段的问题排查

FastAPI中Pydantic模型_id字段无法正常使用的原因及解决办法

为什么_id字段在请求体里拿不到/发不出去?

核心原因是Pydantic的默认规则:以下划线_开头的字段会被默认识别为私有属性,不会参与请求体的解析(反序列化)和响应的序列化过程。这是遵循Python的命名习惯——下划线开头的变量通常表示内部使用的属性。

举个例子,你定义的模型如果是这样:

from pydantic import BaseModel

class Product(BaseModel):
    _id: str
    name: str

FastAPI会自动忽略_id字段,不管是请求里传这个字段,还是响应里要返回它,都不会生效。

为什么移除返回模型后能拿到_id?

当你去掉API的返回模型声明时,FastAPI不会经过Pydantic的序列化处理,而是直接返回原始的数据对象(比如MongoDB查询出来的字典/BSON对象)。这时候_id属于原始数据的一部分,自然会被返回。

不用改成id,这样处理就能解决问题

你完全没必要把_id改成id,用下面几种方法就能让Pydantic正常处理_id:

方法1:给字段设置别名(推荐)

如果你的数据源(比如MongoDB)本身用的是_id,可以给模型字段设置别名,同时允许按字段名赋值:

from pydantic import BaseModel, Field

class Product(BaseModel):
    id: str = Field(alias="_id")
    
    class Config:
        allow_population_by_field_name = True

这样一来,请求体里传_id会被映射到模型的id属性,响应时也会自动转成_id返回,完美适配MongoDB的字段名。

方法2:关闭下划线字段的私有属性识别

如果你想直接保留_id作为模型字段名,可以修改模型的Config,告诉Pydantic下划线开头的字段不是私有属性:

from pydantic import BaseModel

class Product(BaseModel):
    _id: str
    
    class Config:
        underscore_attrs_are_private = False

设置后,_id就能正常被FastAPI解析和返回。

方法3:处理MongoDB的ObjectId类型

如果你的_id是MongoDB的ObjectId类型,还需要额外处理类型转换,避免序列化报错:

from pydantic import BaseModel, Field
from bson import ObjectId
from pydantic.json import ENCODERS_BY_TYPE

# 给ObjectId注册字符串编码器
ENCODERS_BY_TYPE[ObjectId] = str

class Product(BaseModel):
    _id: ObjectId = Field(alias="_id")
    
    class Config:
        allow_population_by_field_name = True
        arbitrary_types_allowed = True

这样就能正确解析MongoDB的_id,并且响应时自动转成字符串返回。

要不要改成id字段?

完全没必要,上面的方法都能完美保留_id的使用场景。除非你的业务逻辑更倾向于用id作为字段名,否则不需要修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:47:13