gpt4 book ai didi

python - 在从 pydantic.BaseModel 创建的 JSON 中,如果未设置,则排除可选

转载 作者:行者123 更新时间:2023-12-03 23:01:38 28 4
gpt4 key购买 nike

我想排除所有在创建 JSON 时未设置的 Optional 值。在这个例子中:

from pydantic import BaseModel
from typing import Optional


class Foo(BaseModel):
x: int
y: int = 42
z: Optional[int]


print(Foo(x=3).json())
我收到 {"x": 3, "y": 42, "z": null} .但我想排除 z .不是因为它的值是 None , 但因为它是 Optional 并且没有 z 的关键字参数.在下面的两种情况下,我想要 z在 JSON 中。
Foo(x=1, z=None)
Foo(x=1, z=77)
如果有任何其他解决方案可以设置 z从这个意义上讲,我希望看到它。

最佳答案

您可以仅排除未设置的可选模型字段,方法是建立 的模型字段的并集。已设置 和那些不是无 .
Pydantic 为导出方法提供以下参数 model.dict(...) :

exclude_unset: whether fields which were not explicitly set when creating the model should be excluded from the returned dictionary; default False.

exclude_none: whether fields which are equal to None should be excluded from the returned dictionary; default False


要合并两个字典,我们可以使用表达式 a = {**b, **c} (来自 c 的值覆盖来自 b 的值)。请注意,从 Python 3.9 开始,它可以像 a = b | c 一样完成。 .
from pydantic import BaseModel
from typing import Optional
from pydantic.json import pydantic_encoder
import json


class Foo(BaseModel):
x: int
y: int = 42
z: Optional[int]

def exclude_optional_dict(model: BaseModel):
return {**model.dict(exclude_unset=True), **model.dict(exclude_none=True)}

def exclude_optional_json(model: BaseModel):
return json.dumps(exclude_optional_dict(model), default=pydantic_encoder)



print(exclude_optional_json(Foo(x=3))) # {"x": 3, "y": 42}
print(exclude_optional_json(Foo(x=3, z=None))) # {"x": 3, "z": null, "y": 42}
print(exclude_optional_json(Foo(x=3, z=77))) # {"x": 3, "z": 77, "y": 42}
更新
为了使用嵌套模型的方法,我们需要对两个字典进行深度联合(或合并),如下所示:
def union(source, destination):
for key, value in source.items():
if isinstance(value, dict):
node = destination.setdefault(key, {})
union(value, node)
else:
destination[key] = value

return destination

def exclude_optional_dict(model: BaseModel):
return union(model.dict(exclude_unset=True), model.dict(exclude_none=True))

class Foo(BaseModel):
x: int
y: int = 42
z: Optional[int]

class Bar(BaseModel):
a: int
b: int = 52
c: Optional[int]
d: Foo


print(exclude_optional_json(Bar(a=4, d=Foo(x=3))))
print(exclude_optional_json(Bar(a=4, c=None, d=Foo(x=3, z=None))))
print(exclude_optional_json(Bar(a=4, c=78, d=Foo(x=3, z=77))))
{"a": 4, "b": 52, "d": {"x": 3, "y": 42}}
{"a": 4, "b": 52, "d": {"x": 3, "y": 42, "z": null}, "c": null}
{"a": 4, "b": 52, "c": 78, "d": {"x": 3, "y": 42, "z": 77}}

关于python - 在从 pydantic.BaseModel 创建的 JSON 中,如果未设置,则排除可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65362524/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com