我使用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))
答案 0 :(得分:19)
现在可以使用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)
答案 1 :(得分:3)
要确认并扩展先前的answer,请在pydantic-github处给出“正式”答案-所有功劳归于“ dmontagu ”:
在pydantic中执行此操作的“正确”方法是利用“自定义根” 类型”。您仍然需要使用容器模型:
class UserList(BaseModel):
__root__: List[User]
but then the following will work:
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']},
])
(并将这些值放在 root 属性中)。
不幸的是,我认为没有很好的序列化支持 这还没有,所以我想如果您想返回结果 仅返回一个列表,您仍然需要返回UserList。 root 。
我认为目前没有统一的界面可以让您 该模型的序列化/非结构化版本 root_model ,但是如果您正在寻找它,那么可能值得构建。
答案 2 :(得分:0)
您可以尝试
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())
答案 3 :(得分:0)
您可以考虑使用列表理解以及将dict解压缩到User
构造函数中
user_list = [
User(**user) for user in users
]
答案 4 :(得分:0)
您可以使用__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网络框架可以对user_list
进行JSON加密,以JSON数组的形式返回(在响应体内)。
答案 5 :(得分:0)
如果低于 1.2 的 pydantic 版本不支持 parse_obj_as 方法,我还有另一个想法来简化此代码。
user_list = []
for user in users:
user_list.append(User(**user))
简单的方法
user_list = [User(**user) for user in users]