8.2 KiB
Body - Обновления
Полное обновление с помощью PUT
Для полного обновления элемента можно воспользоваться операцией HTTP PUT
.
Вы можете использовать функцию jsonable_encoder
для преобразования входных данных в JSON, так как нередки случаи, когда работать можно только с простыми типами данных (например, для хранения в NoSQL-базе данных).
=== "Python 3.10+"
```Python hl_lines="28-33"
{!> ../../../docs_src/body_updates/tutorial001_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="30-35"
{!> ../../../docs_src/body_updates/tutorial001_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="30-35"
{!> ../../../docs_src/body_updates/tutorial001.py!}
```
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
, без учета значений по умолчанию. Затем вы можете использовать это для создания словаря только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию:
=== "Python 3.10+"
```Python hl_lines="32"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="34"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="34"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
Использование параметра update
в Pydantic
Теперь можно создать копию существующей модели, используя .copy()
, и передать параметр update
с dict
, содержащим данные для обновления.
Например, stored_item_model.copy(update=update_data)
:
=== "Python 3.10+"
```Python hl_lines="33"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="35"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="35"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
Кратко о частичном обновлении
В целом, для применения частичных обновлений необходимо:
- (Опционально) использовать
PATCH
вместоPUT
. - Извлечь сохранённые данные.
- Поместить эти данные в Pydantic модель.
- Сгенерировать
dict
без значений по умолчанию из входной модели (с использованиемexclude_unset
).- Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять значения, уже сохраненные в модели по умолчанию.
- Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметра
update
). - Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощью
jsonable_encoder
).- Это сравнимо с повторным использованием метода модели
.dict()
, но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например,datetime
вstr
.
- Это сравнимо с повторным использованием метода модели
- Сохранить данные в своей БД.
- Вернуть обновленную модель.
=== "Python 3.10+"
```Python hl_lines="28-35"
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="30-37"
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="30-37"
{!> ../../../docs_src/body_updates/tutorial002.py!}
```
!!! tip "Подсказка"
Эту же технику можно использовать и для операции HTTP PUT
.
Но в приведенном примере используется `PATCH`, поскольку он был создан именно для таких случаев использования.
!!! note "Технические детали" Обратите внимание, что входная модель по-прежнему валидируется.
Таким образом, если вы хотите получать частичные обновления, в которых могут быть опущены все атрибуты, вам необходимо иметь модель, в которой все атрибуты помечены как необязательные (со значениями по умолчанию или `None`).
Чтобы отличить модели со всеми необязательными значениями для **обновления** от моделей с обязательными значениями для **создания**, можно воспользоваться идеями, описанными в [Дополнительные модели](extra-models.md){.internal-link target=_blank}.