You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.1 KiB

Body - Обновления

Полное обновление с помощью PUT

Для полного обновления элемента можно воспользоваться операцией HTTP PUT.

Вы можете использовать функцию jsonable_encoder для преобразования входных данных в JSON, так как нередки случаи, когда работать можно только с простыми типами данных (например, для хранения в NoSQL-базе данных).

{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}

PUT используется для получения данных, которые должны полностью заменить существующие данные.

Предупреждение о замене

Это означает, что если вы хотите обновить элемент bar, используя PUT с телом, содержащим:

{
    "name": "Barz",
    "price": 3,
    "description": None,
}

поскольку оно не включает уже сохраненный атрибут "tax": 20.2, входная модель примет значение по умолчанию "tax": 10.5.

И данные будут сохранены с этим "новым" tax, равным 10,5.

Частичное обновление с помощью PATCH

Также можно использовать HTTP PATCH операцию для частичного обновления данных.

Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми.

/// note | Технические детали

PATCH менее распространен и известен, чем PUT.

А многие команды используют только PUT, даже для частичного обновления.

Вы можете свободно использовать их как угодно, FastAPI не накладывает никаких ограничений.

Но в данном руководстве более или менее понятно, как они должны использоваться.

///

Использование параметра exclude_unset в Pydantic

Если необходимо выполнить частичное обновление, то очень полезно использовать параметр exclude_unset в методе .dict() модели Pydantic.

Например, item.dict(exclude_unset=True).

В результате будет сгенерирован словарь, содержащий только те данные, которые были заданы при создании модели item, без учета значений по умолчанию. Затем вы можете использовать это для создания словаря только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию:

{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}

Использование параметра update в Pydantic

Теперь можно создать копию существующей модели, используя .copy(), и передать параметр update с dict, содержащим данные для обновления.

Например, stored_item_model.copy(update=update_data):

{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}

Кратко о частичном обновлении

В целом, для применения частичных обновлений необходимо:

  • (Опционально) использовать PATCH вместо PUT.
  • Извлечь сохранённые данные.
  • Поместить эти данные в Pydantic модель.
  • Сгенерировать dict без значений по умолчанию из входной модели (с использованием exclude_unset).
    • Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять значения, уже сохраненные в модели по умолчанию.
  • Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметра update).
  • Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощью jsonable_encoder).
    • Это сравнимо с повторным использованием метода модели .dict(), но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например, datetime в str.
  • Сохранить данные в своей БД.
  • Вернуть обновленную модель.

{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}

/// tip | Подсказка

Эту же технику можно использовать и для операции HTTP PUT.

Но в приведенном примере используется PATCH, поскольку он был создан именно для таких случаев использования.

///

/// note | Технические детали

Обратите внимание, что входная модель по-прежнему валидируется.

Таким образом, если вы хотите получать частичные обновления, в которых могут быть опущены все атрибуты, вам необходимо иметь модель, в которой все атрибуты помечены как необязательные (со значениями по умолчанию или None).

Чтобы отличить модели со всеми необязательными значениями для обновления от моделей с обязательными значениями для создания, можно воспользоваться идеями, описанными в Дополнительные модели{.internal-link target=_blank}.

///