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

如何让Pydantic对象dict()方法返回自定义类型的字符串表示

解决Pydantic自定义类型序列化为字符串的问题

针对你的需求,要让MongoId类型在调用dict()(Pydantic v2中为model_dump())时返回字符串而非ObjectId实例,有两种直接有效的实现方式:

方法一:为模型字段添加序列化器

在User模型中,使用@field_serializer装饰器单独处理uid字段的序列化逻辑,将MongoId实例转为字符串:

from pydantic import BaseModel, field_serializer
from bson import ObjectId

class MongoId(ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if isinstance(v, str):
            return ObjectId(v)
        if not isinstance(v, ObjectId):
            raise ValueError("Invalid ObjectId")
        return v

class User(BaseModel):
    uid: MongoId

    @field_serializer('uid')
    def serialize_uid(self, value: MongoId) -> str:
        return str(value)

# 测试
user = User(uid="507f1f77bcf86cd799439011")
print(user.dict())  # 输出: {'uid': '507f1f77bcf86cd799439011'}

方法二:在自定义类型中全局配置序列化逻辑

如果希望所有使用MongoId的字段都自动序列化为字符串,无需在每个模型中重复编写序列化器,可以在MongoId类中实现__get_pydantic_core_schema__方法,统一指定序列化规则:

from pydantic import BaseModel, GetCoreSchemaHandler
from pydantic_core import core_schema
from bson import ObjectId

class MongoId(ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if isinstance(v, str):
            return ObjectId(v)
        if not isinstance(v, ObjectId):
            raise ValueError("Invalid ObjectId")
        return v

    @classmethod
    def __get_pydantic_core_schema__(cls, source_type, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
        # 获取基础校验规则
        base_schema = handler(source_type)
        # 配置序列化逻辑:将MongoId实例转为字符串
        return core_schema.no_info_wrap_validator_function(
            cls.validate,
            core_schema.union_schema([
                core_schema.str_schema(),
                core_schema.is_instance_schema(ObjectId)
            ]),
            serialization=core_schema.plain_serializer_function_ser_schema(str)
        )

class User(BaseModel):
    uid: MongoId

# 测试
user = User(uid="507f1f77bcf86cd799439011")
print(user.dict())  # 输出: {'uid': '507f1f77bcf86cd799439011'}

说明

你之前尝试让自定义类型继承BaseModel并实现dict()方法无效,原因是:MongoId本质是ObjectId的子类,继承BaseModel会打破原有类型的继承关系,且BaseModel的dict()方法是用于序列化模型自身字段的,无法直接覆盖单个自定义类型的序列化行为。正确的思路是针对Pydantic的序列化逻辑进行配置,而非修改类型的继承体系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:25:40