JavaRush /Курсы /Модуль 4: FastAPI /Пример сложной модели с вложенными данными

Пример сложной модели с вложенными данными

Модуль 4: FastAPI
3 уровень , 8 лекция
Открыта

Сегодня мы углубимся в создание сложных моделей с несколькими уровнями вложенности. Это позволит вам эффективно обрабатывать данные даже в объёмных и комплексных структурах, таких как JSON, где вложенность неизбежна. Да, JSON-структуры могут быть такими же замысловатыми, как очередной способ программиста уклониться от комментариев в коде, но вместе мы справимся!

В реальных проектах вы часто сталкиваетесь с ситуациями, когда необходимо работать не с одномерными данными (например, просто именем пользователя или возрастом), а с более сложными структурами. Представьте себе, что вам нужно создать API для регистрации компании, её сотрудников и их контактной информации. Эти данные имеют вложенную структуру. Pydantic позволяет описывать и валидировать такие структуры данных простыми и читаемыми моделями.

Эти навыки пригодятся вам:

  • При разработке API для сложных систем (например, CRM, ERP);
  • При интеграции с внешними сервисами, где используются сложные JSON-ответы;
  • При проектировании модели данных в микросервисной архитектуре.

Создаём сложную модель

Давайте начнём с примера. Допустим, мы создаём API для системы управления проектами. У нас есть сущности: проект, задачи в проекте и ответственные за задачи пользователи.

Вот пример структуры данных, которую мы хотим получить:


{
  "id": 1,
  "name": "FastAPI Development",
  "tasks": [
    {
      "id": 101,
      "title": "Set up project",
      "completed": false,
      "assigned_to": {
        "id": 501,
        "name": "Alice",
        "email": "alice@example.com"
      }
    },
    {
      "id": 102,
      "title": "Add authentication",
      "completed": true,
      "assigned_to": {
        "id": 502,
        "name": "Bob",
        "email": "bob@example.com"
      }
    }
  ]
}

Приступим к реализации модели.

Базовые модели

Сначала создадим модель для пользователя, так как она используется в задаче.


from pydantic import BaseModel, EmailStr

class User(BaseModel):
    id: int
    name: str
    email: EmailStr

Здесь всё просто: id — это идентификатор пользователя, name — его имя, а email — электронная почта (мы используем тип EmailStr, чтобы автоматически валидировать формат email).

Теперь создадим модель для задачи.


from typing import Optional
from pydantic import BaseModel

class Task(BaseModel):
    id: int
    title: str
    completed: bool
    assigned_to: User | None  # Поле может быть None

Модель Task содержит:

  • id — идентификатор задачи;
  • title — название задачи;
  • completed — булевое значение, отражающее статус задачи;
  • assigned_to — информация о пользователе, которому назначена задача. Обратите внимание, что это поле имеет тип User! Это и есть вложенность. Поле указано как Optional, т.е. задача может быть без назначенного пользователя.

Модель проекта

Теперь создадим модель для проекта, которая включает список задач.


from typing import List

class Project(BaseModel):
    id: int
    name: str
    tasks: List[Task]  # Список задач

Модель Project содержит:

  • id — идентификатор проекта;
  • name — название проекта;
  • tasks — список объектов Task. Используем List[Task] из модуля typing.

Пример сложной модели

Соединим всё вместе и протестируем.


from fastapi import FastAPI

app = FastAPI()

@app.post("/projects/")
def create_project(project: Project):
    return {"message": "Project successfully created!", "data": project}

Запустите приложение с помощью uvicorn. Вот пример запроса, который мы можем отправить:


{
  "id": 1,
  "name": "FastAPI Development",
  "tasks": [
    {
      "id": 101,
      "title": "Set up project",
      "completed": false,
      "assigned_to": {
        "id": 501,
        "name": "Alice",
        "email": "alice@example.com"
      }
    },
    {
      "id": 102,
      "title": "Add authentication",
      "completed": true,
      "assigned_to": {
        "id": 502,
        "name": "Bob",
        "email": "bob@example.com"
      }
    }
  ]
}

И вы получите следующий ответ:


{
  "message": "Project successfully created!",
  "data": {
    "id": 1,
    "name": "FastAPI Development",
    "tasks": [
      {
        "id": 101,
        "title": "Set up project",
        "completed": false,
        "assigned_to": {
          "id": 501,
          "name": "Alice",
          "email": "alice@example.com"
        }
      },
      {
        "id": 102,
        "title": "Add authentication",
        "completed": true,
        "assigned_to": {
          "id": 502,
          "name": "Bob",
          "email": "bob@example.com"
        }
      }
    ]
  }
}

Работа с валидацией в сложных структурах

Pydantic автоматически проверяет каждое поле на соответствие указанному типу. Если какое-либо поле не соответствует, будет выброшена ошибка валидации.

Например, отправим запрос с неправильным email у пользователя:


{
  "id": 1,
  "name": "FastAPI Development",
  "tasks": [
    {
      "id": 101,
      "title": "Set up project",
      "completed": false,
      "assigned_to": {
        "id": 501,
        "name": "Alice",
        "email": "alice_at_example.com"
      }
    }
  ]
}

Ответ:


{
  "detail": [
    {
      "loc": ["body", "tasks", 0, "assigned_to", "email"],
      "msg": "value is not a valid email address",
      "type": "value_error.email"
    }
  ]
}

Это сообщение об ошибке показывает путь, где именно возникла ошибка: в первом элементе списка tasks в поле email.


Полезные советы

  1. Сложные структуры лучше разбивать на отдельные модели. Не пытайтесь "запихнуть всё в одну модель". Это усложняет её поддержку.
  2. Используйте описательные имена. Названия моделей и полей должны быть понятными.
  3. Тестируйте вложенные структуры. Иногда ошибка в одном из уровней может быть неочевидной.

Применение в реальных проектах

Сложные вложенные модели находят применение в любой системе, работающей с иерархическими данными. Например:

  • Системы управления задачами (Trello, Jira);
  • E-commerce платформы (товары, категории, магазины);
  • Интеграция с внешними API, особенно когда данные содержат вложенные JSON-объекты.

Теперь вы знаете, как проектировать и валидировать сложные модели с помощью Pydantic. Готовы к задачам реального мира? Поехали в следующие лекции!

1
Задача
Модуль 4: FastAPI, 3 уровень, 8 лекция
Недоступна
Работа с массивом вложенных объектов
Работа с массивом вложенных объектов
1
Задача
Модуль 4: FastAPI, 3 уровень, 8 лекция
Недоступна
Сложная модель с несколькими уровнями вложенности
Сложная модель с несколькими уровнями вложенности
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ