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

如何序列化带有自引用的Pydantic模型FileSystemEntry?

解决Pydantic自引用模型的JSON序列化循环引用问题

你的FileSystemEntry模型中,parent与children形成了双向引用关系,序列化时会触发循环检测报错。以下是几种可行的解决方法:

方法1:序列化时排除循环引用字段

如果业务上不需要保留parent字段的完整信息,可以在序列化时直接排除该字段,避免循环:

# 使用model_dump_json直接排除parent
json_str = entry.model_dump_json(exclude={"parent"})

# 或者用model_dump后自行处理
data = entry.model_dump(exclude={"parent"})

方法2:自定义字段序列化器,将引用转为ID

如果需要保留关联信息但不想序列化完整对象,可以通过字段序列化器将parent和children转为对应的ID:

from pydantic import BaseModel, field_serializer, AnyHttpUrl
from typing import List, Optional

class FileSystemEntry(BaseModel):
    id: str
    path: Optional[str] = None
    mime_type: Optional[str] = None
    is_directory: bool
    parent: Optional["FileSystemEntry"] = None
    children: List["FileSystemEntry"] = []
    share_link: Optional[AnyHttpUrl] = None

    @field_serializer("parent", when_used="always")
    def serialize_parent(self, parent: Optional["FileSystemEntry"]) -> Optional[str]:
        return parent.id if parent else None

    @field_serializer("children", when_used="always")
    def serialize_children(self, children: List["FileSystemEntry"]) -> List[str]:
        return [child.id for child in children]

# 此时直接序列化即可
json_str = entry.model_dump_json()

方法3:使用Self类型简化模型定义(可选)

如果你使用Python 3.10+,可以用Self类型替代字符串注解,让模型定义更清晰,同时不影响序列化逻辑:

from pydantic import BaseModel, Self, field_serializer, AnyHttpUrl
from typing import List, Optional

class FileSystemEntry(BaseModel):
    id: str
    path: Optional[str] = None
    mime_type: Optional[str] = None
    is_directory: bool
    parent: Optional[Self] = None
    children: List[Self] = []
    share_link: Optional[AnyHttpUrl] = None

    # 同样可以加上上述的字段序列化器

方法4:自定义全局JSON序列化逻辑

如果需要更灵活的控制,可以结合标准库的json.dumps自定义序列化函数:

import json
from pydantic import BaseModel, AnyHttpUrl
from typing import List, Optional

class FileSystemEntry(BaseModel):
    id: str
    path: Optional[str] = None
    mime_type: Optional[str] = None
    is_directory: bool
    parent: Optional["FileSystemEntry"] = None
    children: List["FileSystemEntry"] = []
    share_link: Optional[AnyHttpUrl] = None

def serialize_entry(obj):
    if isinstance(obj, FileSystemEntry):
        data = obj.model_dump()
        # 将parent转为ID,children转为ID列表
        data["parent"] = obj.parent.id if obj.parent else None
        data["children"] = [child.id for child in obj.children]
        return data
    raise TypeError(f"无法序列化类型为{type(obj)}的对象")

# 使用自定义函数序列化
json_str = json.dumps(entry, default=serialize_entry)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:46:26