3.8 KiB
请求体 - 更新数据
用 PUT 替换式更新
更新数据可以使用 HTTP PUT 操作。
把输入数据转换为以 JSON 格式存储的数据(比如,使用 NoSQL 数据库时),可以使用 jsonable_encoder。例如,把 datetime 转换为 str。
{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
PUT 用于接收替换现有数据的数据。
关于替换的警告
用 PUT 把数据项 bar 更新为以下请求体时:
{
"name": "Barz",
"price": 3,
"description": None,
}
因为其中未包含已存储的属性 "tax": 20.2,输入模型会取 "tax": 10.5 的默认值。
因此,保存的数据会带有这个“新的” tax 值 10.5。
用 PATCH 进行部分更新
也可以使用 HTTP PATCH 操作对数据进行部分更新。
也就是说,你只需发送想要更新的数据,其余数据保持不变。
/// note | 注意
PATCH 没有 PUT 知名,也没那么常用。
很多团队甚至只用 PUT 实现部分更新。
你可以随意选择如何使用它们,FastAPI 不做任何限制。
但本指南会大致展示它们的预期用法。
///
使用 Pydantic 的 exclude_unset 参数
如果要接收部分更新,建议在 Pydantic 模型的 .model_dump() 中使用 exclude_unset 参数。
比如,item.model_dump(exclude_unset=True)。
这会生成一个 dict,只包含创建 item 模型时显式设置的数据,不包含默认值。
然后再用它生成一个只含已设置(在请求中发送)数据、且省略默认值的 dict:
{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
使用 Pydantic 的 update 参数
接下来,用 .model_copy() 为已有模型创建副本,并传入 update 参数,值为包含更新数据的 dict。
例如,stored_item_model.model_copy(update=update_data):
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
部分更新小结
简而言之,应用部分更新应当:
- (可选)使用
PATCH而不是PUT。 - 提取已存储的数据。
- 把该数据放入 Pydantic 模型。
- 生成不含输入模型默认值的
dict(使用exclude_unset)。- 这样只会更新用户实际设置的值,而不会用模型中的默认值覆盖已存储的值。
- 为已存储的模型创建副本,用接收到的部分更新数据更新其属性(使用
update参数)。 - 把模型副本转换为可存入数据库的形式(比如,使用
jsonable_encoder)。- 这类似于再次调用模型的
.model_dump()方法,但会确保(并转换)值为可转换为 JSON 的数据类型,例如把datetime转换为str。
- 这类似于再次调用模型的
- 把数据保存至数据库。
- 返回更新后的模型。
{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
/// tip | 提示
实际上,HTTP PUT 也可以使用同样的技巧。
但这里用 PATCH 举例,因为它就是为这种用例设计的。
///
/// note | 注意
注意,输入模型仍会被验证。
因此,如果希望接收的部分更新可以省略所有属性,则需要一个所有属性都标记为可选(带默认值或 None)的模型。
为了区分用于更新(全部可选)和用于创建(必填)的模型,可以参考更多模型{.internal-link target=_blank} 中介绍的思路。
///