如何使用 Pydantic 解析模型列表
How to parse list of models with Pydantic
我使用 Pydantic 对 API 的请求和响应进行建模。
我定义了一个User
class:
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
我的 API returns 我用 requests
检索并转换成字典的用户列表:
users = [{"name": "user1", "age": 15}, {"name": "user2", "age": 28}]
如何将此字典转换为 User
个实例的列表?
我现在的解决方案是
user_list = []
for user in users:
user_list.append(User(**user))
你可以试试这个
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())
您可以考虑使用列表理解以及对 User
构造函数
的字典解包
user_list = [
User(**user) for user in users
]
您可以使用 __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 网络框架可以 jsonify user_list
作为 JSON 数组返回(在响应主体内)。
确认并扩展之前的 , here is an "official" answer at pydantic-github - 所有功劳归于“dmontagu”:
The "right" way to do this in pydantic is to make use of "Custom Root
Types". You still need to make use of a container model:
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']},
])
(and will put the values inside the root property).
Unfortunately, I think there is not good serialization support for
this yet, so I think when you go to return the results, if you want to
return just a list you'll still need to return UserList.root.
I don't think there is currently a unified interface that gets you a
serialized/unstructured version of the model that respects the
root_model, but if this is what you are looking for, it could be worth building.
现在可以使用 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)
如果 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]
我只是在我的 models.py
列表中这样设置:
from django.db import models
from pydantic import BaseModel
class CustomList(BaseModel):
data: list[dict]
我使用 Pydantic 对 API 的请求和响应进行建模。
我定义了一个User
class:
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
我的 API returns 我用 requests
检索并转换成字典的用户列表:
users = [{"name": "user1", "age": 15}, {"name": "user2", "age": 28}]
如何将此字典转换为 User
个实例的列表?
我现在的解决方案是
user_list = []
for user in users:
user_list.append(User(**user))
你可以试试这个
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())
您可以考虑使用列表理解以及对 User
构造函数
user_list = [
User(**user) for user in users
]
您可以使用 __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 网络框架可以 jsonify user_list
作为 JSON 数组返回(在响应主体内)。
确认并扩展之前的
The "right" way to do this in pydantic is to make use of "Custom Root Types". You still need to make use of a container model:
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']},
])
(and will put the values inside the root property).
Unfortunately, I think there is not good serialization support for this yet, so I think when you go to return the results, if you want to return just a list you'll still need to return UserList.root.
I don't think there is currently a unified interface that gets you a serialized/unstructured version of the model that respects the root_model, but if this is what you are looking for, it could be worth building.
现在可以使用 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)
如果 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]
我只是在我的 models.py
列表中这样设置:
from django.db import models
from pydantic import BaseModel
class CustomList(BaseModel):
data: list[dict]