如何编写 Pydantic 模型来接受字典字典

sno*_*6oy 7 python pydantic fastapi

下面的代码是根据 Pydantic 文档修改的 ,我想知道如何更改BarModelFooBarModel因此它们接受分配给m1. 我尝试过使用__root__和 语法,但Dict[str, BarModel]一直无法找到神奇的组合。

from pydantic import BaseModel

class BarModel(BaseModel):
    whatever: float
    foo: str

class FooBarModel(BaseModel):
    banana: str
    bar: BarModel

m = FooBarModel(banana='a', bar={'whatever': 12.3, 'foo':'hello'})
m1 = FooBarModel({
  'a':{'whatever': 12.3, 'foo':'hello'},
  'b':{'whatever': 12.4, 'foo':'bye'}
})

print(m.dict())   # returns a dictionary:
print(m1.dict())  # TypeError
Run Code Online (Sandbox Code Playgroud)

最终的解决方案将部署在 FastAPI 上下文中。

Jas*_*ves 11

如果您想做的只是BarModel在另一个模型中拥有 s 的字典,那么这可以回答您的问题:

from typing import Dict
from pydantic import BaseModel

class BarModel(BaseModel):
    whatever: float
    foo: str

class FooBarModel(BaseModel):
    dictionaries: Dict[str, BarModel]

m1 = FooBarModel(dictionaries={
    'a': {'whatever': 12.3, 'foo': 'hello'},
    'b': {'whatever': 12.4, 'foo': 'bye'}
}

print(m1.dict())
Run Code Online (Sandbox Code Playgroud)


Yag*_*nci 5

你已经找到了你的神奇组合,只是你还没有意识到而已。

from pydantic import BaseModel
from typing import Dict

class BarModel(BaseModel):
    whatever: float
    foo: str

class FooBarModel(BaseModel):
    banana: str
    bar: Dict[str, BarModel]


m1 = FooBarModel(banana="a", bar={
  'a':{'whatever': 12.3, 'foo':'hello'},
  'b':{'whatever': 12.4, 'foo':'bye'}
})

assert m1.dict() == {'banana': 'a', 'bar': {'a': {'whatever': 12.3, 'foo': 'hello'}, 'b': {'whatever': 12.4, 'foo': 'bye'}}}
Run Code Online (Sandbox Code Playgroud)

这运行没有任何错误。

注意,我们还有香蕉,如果你想丢弃它,只需删除即可。

如果您想使用纯类型和一些静态分析器,您的示例将对此进行评估

from typing import Dict, Union
m = FooBarModel(banana='a', bar={'whatever': 12.3, 'foo':'hello'})


m: Dict[str, Union[str, Dict[str, Union[float, str]]]]
Run Code Online (Sandbox Code Playgroud)

但你想要的其实是这个

from typing import Dict, Union

m1 = FooBarModel({
  'a':{'whatever': 12.3, 'foo':'hello'},
  'b':{'whatever': 12.4, 'foo':'bye'}
})

m1: Dict[str, Union[str, Dict[str, Dict[str, Union[float, str]]]]]
Run Code Online (Sandbox Code Playgroud)