pydantic 中的自参考模型

问题描述 投票:0回答:1

我想序列化一个具有自引用的结构:

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

如何做?显然,当尝试将其转储为 JSON 时,我有

pydantic_core._pydantic_core.PydanticSerializationError: Error serializing to JSON: ValueError: Circular reference detected (id repeated)

任何帮助将不胜感激

python recursion filesystems pydantic
1个回答
0
投票

在您的情况下,需要编写自定义序列化方法来处理循环引用。

from typing import List, Dict, Union
from pydantic import BaseModel, AnyHttpUrl

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

    def to_serializable(self) -> Dict:
        """Converts the model to a dictionary format that can be serialized."""
        # Serialize without children to avoid circular references
        serialized_data = self.dict(exclude={'children', 'parent'})
        # Manually serialize the children and parent (only ID for simplicity)
        if self.parent:
            serialized_data['parent'] = self.parent.id
        serialized_data['children'] = [child.id for child in self.children]
        return serialized_data

# Example usage
parent_entry = FileSystemEntry(id="1", path="/", is_directory=True)
child_entry = FileSystemEntry(id="2", path="/child", is_directory=False, parent=parent_entry)

parent_entry.children.append(child_entry)

print(parent_entry.to_serializable())
© www.soinside.com 2019 - 2024. All rights reserved.