FastAPI для начинающих: API с базой данных и тестамиВходные данные и Pydantic v2Модели создания и ответа

Модели создания и ответа

Уроки курсаМодели создания и ответа

response_model: проверка ответа и исключение внутреннего поля

response_model подключается в декораторе маршрута. Ниже самостоятельный полный main.py с сокращённой входной моделью. Замените содержимое файла целиком, не добавляйте этот маршрут после старого обработчика:

from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()

class RoomIn(BaseModel):
    name: str = Field(..., min_length=2, max_length=50)
    capacity: int = Field(..., ge=1, le=50)

class RoomOut(BaseModel):
    id: int
    name: str
    capacity: int

@app.post("/api/rooms", response_model=RoomOut)
def create_room(room: RoomIn):
    record = {"id": 1, "name": room.name, "capacity": room.capacity, "internal_note": "служебное"}
    return record

Обработчик возвращает словарь с четырьмя ключами. FastAPI берёт этот словарь, прогоняет через RoomOut и сериализует только поля, объявленные в классе: id, name, capacity. Поле internal_note в RoomOut не объявлено — в JSON-ответе его не будет.

В /docs отправьте POST /api/rooms с телом {"name": "Лондон", "capacity": 6}. Клиент получит статус 200 и JSON:

{"id": 1, "name": "Лондон", "capacity": 6}

Удалять internal_note из словаря вручную перед return не нужно — response_model работает как белый список.

Два разных типа ошибок. Если клиент прислал некорректные данные — нарушены ограничения RoomIn — FastAPI вернёт 422 Unprocessable Entity ещё до вызова обработчика. Это ошибка входа.

Если обработчик вернул словарь, в котором нет обязательного поля RoomOut (например, забыли добавить id), FastAPI попытается собрать RoomOut из этого словаря и не сможет. Результат — 500 Internal Server Error. Это ошибка ответа: контракт, который сервер обещал, не выполнен. FastAPI не придумывает значения для обязательных полей response_model.

Различие важно: 422 говорит клиенту, что он прислал плохой запрос; 500 — что сервер сломан. При разработке второй сценарий сразу видно в логах, и это правильно: такая ошибка означает баг в обработчике, а не проблему клиента.

Обработчик возвращает словарь с id 1, name Лондон, capacity 6 и internal_note служебное. FastAPI применяет response_model=RoomOut с полями id, name, capacity. JSON-ответ содержит только эти три поля; internal_note исключено. Демонстрационный id 1 задан обработчиком.
RoomOut проверяет результат и оставляет в JSON только свои поля. Демонстрационный id=1 добавлен обработчиком; схема ответа не назначает идентификаторы.