34

我使用 Pydantic 对 API 的请求和响应进行建模。

我定义了一个User类:

from pydantic import BaseModel

class User(BaseModel):
  name: str
  age: int

我的 API 返回一个用户列表,我用它检索requests并转换为字典:

users = [{"name": "user1", "age": 15}, {"name": "user2", "age": 28}]

如何将此字典转换为User实例列表?

我现在的解决方案是

user_list = []
for user in users:
  user_list.append(User(**user))
4

7 回答 7

73

现在可以使用parse_obj_as.

from pydantic import parse_obj_as

users = [
    {"name": "user1", "age": 15}, 
    {"name": "user2", "age": 28}
]

m = parse_obj_as(List[User], users)
于 2020-04-03T22:11:53.930 回答
31

为了确认和扩展之前的答案,这里有一个pydantic-github上的“官方”答案——所有学分归于“ dmontagu ”:

在 pydantic 中执行此操作的“正确”方法是使用“自定义根类型”。您仍然需要使用容器模型:

class UserList(BaseModel):
    __root__: List[User]

但随后以下将起作用:

UserList.parse_obj([
    {'id': '123', 'signup_ts': '2017-06-01 12:22', 'friends': [1, '2', b'3']},
    {'id': '456', 'signup_ts': '2017-06-02 12:22', 'friends': ['you']},
])

(并将值放在属性中)。

不幸的是,我认为目前还没有很好的序列化支持,所以我认为当你返回结果时,如果你只想返回一个列表,你仍然需要返回 UserList。

我不认为目前有一个统一的界面可以为您提供尊重 root_model的模型的序列化/非结构化版本,但如果这是您正在寻找的,那么它可能值得构建。

于 2019-10-31T10:17:44.357 回答
7

你可以试试这个

from typing import List
from pydantic import BaseModel

class User(BaseModel):
  name: str
  age: int

class Users(BaseModel):
    users: List[User]

users = [{"name": "user1", "age": 15}, {"name": "user2", "age": 28}]
m = Users(users=users)
print(m.dict())
于 2019-04-19T13:51:34.600 回答
5

您可以考虑使用列表推导以及 dict 解包到User构造函数

user_list = [
  User(**user) for user in users
]
于 2019-08-27T19:53:30.823 回答
4

您可以使用__root__Pydantic 关键字:

from typing import List
from pydantic import BaseModel

class User(BaseModel):
  name: str
  age: int

class UserList(BaseModel):
  __root__: List[User]     # ⯇-- __root__

要构建 JSON 响应:

user1 = {"name": "user1", "age": 15}
user2 = {"name": "user2", "age": 28}

user_list = UserList(__root__=[])
user_list.__root__.append(User(**user1))
user_list.__root__.append(User(**user2))

您的 API Web 框架可以 jsonifyuser_list以作为 JSON 数组(在响应正文中)返回。

于 2019-10-31T03:41:50.893 回答
1

我只是在我models.py的 dict 列表中设置如下:

from django.db import models
from pydantic import BaseModel

class CustomList(BaseModel):
    data: list[dict]
于 2021-09-25T08:45:45.867 回答
0

如果 pydantic 版本低于 1.2 且不支持parse_obj_as方法,我还有另一个想法来简化此代码。

user_list = []
for user in users:
  user_list.append(User(**user))

简单的方法

user_list = [User(**user) for user in users]
于 2021-06-05T10:47:58.780 回答