committed by
GitHub
1 changed files with 153 additions and 0 deletions
@ -0,0 +1,153 @@ |
|||
# Body - Обновления |
|||
|
|||
## Полное обновление с помощью `PUT` |
|||
|
|||
Для полного обновления элемента можно воспользоваться операцией <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>. |
|||
|
|||
Вы можете использовать функцию `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` с телом, содержащим: |
|||
|
|||
```Python |
|||
{ |
|||
"name": "Barz", |
|||
"price": 3, |
|||
"description": None, |
|||
} |
|||
``` |
|||
|
|||
поскольку оно не включает уже сохраненный атрибут `"tax": 20.2`, входная модель примет значение по умолчанию `"tax": 10.5`. |
|||
|
|||
И данные будут сохранены с этим "новым" `tax`, равным `10,5`. |
|||
|
|||
## Частичное обновление с помощью `PATCH` |
|||
|
|||
Также можно использовать <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> операцию для *частичного* обновления данных. |
|||
|
|||
Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми. |
|||
|
|||
!!! 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}. |
Loading…
Reference in new issue