Как я могу проверить рекурсивные модели Pydantic, где правила проверки зависят от динамической глубины вложенности?Python

Программы на Python
Ответить
Anonymous
 Как я могу проверить рекурсивные модели Pydantic, где правила проверки зависят от динамической глубины вложенности?

Сообщение Anonymous »

Я создаю приложение FastAPI и моделирую систему комментариев в стиле форума, используя Pydantic v2.
Каждый комментарий может содержать ответы, и эти ответы могут содержать больше ответов, рекурсивно, подобно темам Reddit или GitHub.
Упрощенная версия моей модели (без пользователя) выглядит следующим образом:

Код: Выделить всё

from __future__ import annotations
from pydantic import BaseModel
from typing import List

class Comment(BaseModel):
id: int
text: str
replies: List[Comment] | None = None

Comment.model_rebuild()
Это отлично работает для базовой проверки.
Однако мне нужно обеспечить соблюдение правила:
Дерево комментариев не должно превышать максимальную глубину вложенности.
Например, максимальная глубина = 3. (Чтобы оно не выглядело некрасиво и не нарушало пользовательский интерфейс). Итак, с полезной нагрузкой:

Код: Выделить всё

{
"id": 1,
"text": "Level 1",
"replies": [
{
"id": 2,
"text": "Level 2",
"replies": [
{
"id": 3,
"text": "Level 3",
"replies": [
{ "id": 4, "text": "Level 4 INVALID" }
]
}
]
}
]
}
Я хочу, чтобы Pydantic выдавал ошибку проверки, поскольку глубина превышает допустимый максимум.
Что я пробовал
Я пытался вычислить глубину внутри field_validator, но поскольку модель проверяет рекурсивно, не зная глубины собственного вызова, я сталкиваюсь с такими проблемами, как RecursionError или невозможность доступа к контексту текущего уровня рекурсии или даже валидаторы, работающие до того, как будут запущены все дочерние элементы. построен.

Код: Выделить всё

from __future__ import annotations
from pydantic import BaseModel, field_validator, ValidationError

MAX_DEPTH = 3

class Comment(BaseModel):
id: int
text: str
replies: list[Comment] | None = None

@field_validator("replies", mode="after")
def validate_depth(cls, replies):
if replies:
depth = cls._compute_depth(replies)
if depth > MAX_DEPTH:
raise ValueError(f"Maximum depth {MAX_DEPTH} exceeded (found: {depth})")
return replies

@classmethod
def _compute_depth(cls, replies):
if not replies:
return 1
return 1 + max(cls._compute_depth(r.replies) for r in replies)

Comment.model_rebuild()
Это работает в случаях BASIC, и я хочу найти лучший подход, или есть ли в Pydantic v2 более идиоматический или встроенный способ обработки рекурсивной проверки с ограничениями глубины?


Подробнее здесь: https://stackoverflow.com/questions/798 ... s-depend-o
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»