如何使用 Pydantic 解析模型列表
Posted
技术标签:
【中文标题】如何使用 Pydantic 解析模型列表【英文标题】:How to parse list of models with Pydantic 【发布时间】:2019-09-09 18:34:00 【问题描述】:我使用 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]
如何将此 dict 转换为 User
实例列表?
我现在的解决方案是
user_list = []
for user in users:
user_list.append(User(**user))
【问题讨论】:
【参考方案1】:现在可以使用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)
【讨论】:
是否有逆向功能,即给定 List[User] 转换 List[dict]【参考方案2】:为了确认和扩展之前的answer,这里是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'],
])
(并将值放在 root 属性中)。
不幸的是,我认为没有很好的序列化支持 这还没有,所以我想当你去返回结果时,如果你想 只返回一个列表,您仍然需要返回 UserList。root。
我认为目前没有一个统一的界面可以让您获得 模型的序列化/非结构化版本,尊重 root_model,但如果这是您正在寻找的,那么它可能值得构建。
【讨论】:
如果您将.json()
用于具有自定义根类型的模型,它将以根对象为根(没有'__root__':
)。
除非您使用.dict()
,否则它将包含__root__
键:)【参考方案3】:
你可以试试这个
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())
【讨论】:
谢谢,但这会返回一个带有users
属性的对象,其中包含列表。如果没有办法做到这一点,我会记住它,那就更好了!【参考方案4】:
您可以考虑使用列表推导以及 dict 解包到 User
构造函数
user_list = [
User(**user) for user in users
]
【讨论】:
我喜欢,很干净 最简单最明显的。应该被接受的答案。 仅供参考,这种方法比接受的答案快大约 2x。我不知道为什么另一个被接受了,哈哈。【参考方案5】:您可以使用__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 框架可以将 user_list
json 化为 JSON 数组(在响应正文中)。
【讨论】:
【参考方案6】:如果 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]
【讨论】:
【参考方案7】:我刚刚在我的 models.py
dict 列表中设置如下:
from django.db import models
from pydantic import BaseModel
class CustomList(BaseModel):
data: list[dict]
【讨论】:
以上是关于如何使用 Pydantic 解析模型列表的主要内容,如果未能解决你的问题,请参考以下文章
如何在 FastAPI 中使用 Pydantic 模型和表单数据?
python - 如何在python中使用带有graphene-pydantic和graphene的子类中的pydantic模型?