Skip to content

Latest commit

 

History

History
99 lines (63 loc) · 5.15 KB

body-updates.md

File metadata and controls

99 lines (63 loc) · 5.15 KB

ボディ - 更新

PUTによる置換での更新

項目を更新するにはHTTPのPUT操作を使用することができます。

jsonable_encoderを用いて、入力データをJSON形式で保存できるデータに変換することができます(例:NoSQLデータベース)。例えば、datetimestrに変換します。

{!../../../docs_src/body_updates/tutorial001.py!}

既存のデータを置き換えるべきデータを受け取るためにPUTは使用されます。

置換についての注意

つまり、PUTを使用して以下のボディで項目barを更新したい場合は:

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

すでに格納されている属性"tax": 20.2を含まないため、入力モデルのデフォルト値は"tax": 10.5です。

そして、データはその「新しい」10.5taxと共に保存されます。

PATCHによる部分的な更新

また、HTTPのPATCH操作でデータを部分的に更新することもできます。

つまり、更新したいデータだけを送信して、残りはそのままにしておくことができます。

!!! note "備考" PATCHPUTよりもあまり使われておらず、知られていません。

また、多くのチームは部分的な更新であっても`PUT`だけを使用しています。

**FastAPI** はどんな制限も課けていないので、それらを使うのは **自由** です。

しかし、このガイドでは、それらがどのように使用されることを意図しているかを多かれ少なかれ、示しています。

Pydanticのexclude_unsetパラメータの使用

部分的な更新を受け取りたい場合は、Pydanticモデルの.dict()exclude_unsetパラメータを使用すると非常に便利です。

item.dict(exclude_unset=True)のように。

これにより、itemモデルの作成時に設定されたデータのみを持つdictが生成され、デフォルト値は除外されます。

これを使うことで、デフォルト値を省略して、設定された(リクエストで送られた)データのみを含むdictを生成することができます:

{!../../../docs_src/body_updates/tutorial002.py!}

Pydanticのupdateパラメータ

ここで、.copy()を用いて既存のモデルのコピーを作成し、updateパラメータに更新するデータを含むdictを渡すことができます。

stored_item_model.copy(update=update_data)のように:

{!../../../docs_src/body_updates/tutorial002.py!}

部分的更新のまとめ

まとめると、部分的な更新を適用するには、次のようにします:

  • (オプションで)PUTの代わりにPATCHを使用します。
  • 保存されているデータを取得します。
  • そのデータをPydanticモデルにいれます。
  • 入力モデルからデフォルト値を含まないdictを生成します(exclude_unsetを使用します)。
    • この方法では、モデル内のデフォルト値ですでに保存されている値を上書きするのではなく、ユーザーが実際に設定した値のみを更新することができます。
  • 保存されているモデルのコピーを作成し、受け取った部分的な更新で属性を更新します(updateパラメータを使用します)。
  • コピーしたモデルをDBに保存できるものに変換します(例えば、jsonable_encoderを使用します)。
    • これはモデルの.dict()メソッドを再度利用することに匹敵しますが、値をJSONに変換できるデータ型、例えばdatetimestrに変換します。
  • データをDBに保存します。
  • 更新されたモデルを返します。
{!../../../docs_src/body_updates/tutorial002.py!}

!!! tip "豆知識" 実際には、HTTPのPUT操作でも同じテクニックを使用することができます。

しかし、これらのユースケースのために作成されたので、ここでの例では`PATCH`を使用しています。

!!! note "備考" 入力モデルがまだ検証されていることに注目してください。

そのため、すべての属性を省略できる部分的な変更を受け取りたい場合は、すべての属性をオプションとしてマークしたモデルを用意する必要があります(デフォルト値または`None`を使用して)。

**更新** のためのオプション値がすべて設定されているモデルと、**作成** のための必須値が設定されているモデルを区別するには、[追加モデル](extra-models.md){.internal-link target=_blank}で説明されている考え方を利用することができます。