pydantic导出模型
1.model.dict(...)
- 将模型转换为字典的主要方法。子模型将递归转换为字典。
- 参数如下:
include
:要包含在返回的字典中的字段exclude
:要从返回的字典中排除的字段by_alias
:字段别名是否应用作返回字典中的键exclude_unset
:创建模型时未显式设置的字段是否应从返回的字典中排除;exclude_defaults
:是否应从返回的字典中排除等于其默认值(无论是否设置)的字段;exclude_none
:是否应从返回的字典中排除等于的字段;
from pydantic import BaseModel
class BarModel(BaseModel):
whatever: int
class FooBarModel(BaseModel):
banana: float
foo: str
bar: BarModel
m = FooBarModel(banana=3.14, foo='hello', bar={'whatever': 123})
# returns a dictionary:
print(m.dict())
"""
{
'banana': 3.14,
'foo': 'hello',
'bar': {'whatever': 123},
}
"""
print(m.dict(include={'foo', 'bar'}))
# {'foo': 'hello', 'bar': {'whatever': 123}}
print(m.dict(exclude={'foo', 'bar'}))
# {'banana': 3.14}
- 高级包含和排除
from pydantic import BaseModel, SecretStr
class User(BaseModel):
id: int
username: str
password: SecretStr
class Transaction(BaseModel):
id: str
user: User
value: int
t = Transaction(
id='1234567890',
user=User(
id=42,
username='JohnDoe',
password='hashedpassword'
),
value=9876543210,
)
# using a set:
print(t.dict(exclude={'user', 'value'})) # {'id': '1234567890'}
# using a dict: 对深层嵌套对象进行处理
print(t.dict(exclude={'user': {'username', 'password'}, 'value': True})) # {'id': '1234567890', 'user': {'id': 42}}
print(t.dict(include={'id': True, 'user': {'id'}})) # {'id': '1234567890', 'user': {'id': 42}}
import datetime
from typing import List
from pydantic import BaseModel, SecretStr
class Country(BaseModel):
name: str
phone_code: int
class Address(BaseModel):
post_code: int
country: Country
class CardDetails(BaseModel):
number: SecretStr
expires: datetime.date
class Hobby(BaseModel):
name: str
info: str
class User(BaseModel):
first_name: str
second_name: str
address: Address
card_details: CardDetails
hobbies: List[Hobby]
user = User(
first_name='John',
second_name='Doe',
address=Address(
post_code=123456,
country=Country(
name='USA',
phone_code=1
)
),
card_details=CardDetails(
number=4212934504460000,
expires=datetime.date(2020, 5, 1)
),
hobbies=[
Hobby(name='Programming', info='Writing code and stuff'),
Hobby(name='Gaming', info='Hell Yeah!!!'),
],
)
exclude_keys = {
'second_name': True,
'address': {'post_code': True, 'country': {'phone_code'}},
'card_details': True,
# You can exclude fields from specific members of a tuple/list by index:
'hobbies': {-1: {'info'}},
}
include_keys = {
'first_name': True,
'address': {'country': {'name'}},
'hobbies': {0: True, -1: {'name'}},
}
# would be the same as user.dict(exclude=exclude_keys) in this case:
print(user.dict(include=include_keys))
"""
{
'first_name': 'John',
'address': {'country': {'name': 'USA'}},
'hobbies': [
{
'name': 'Programming',
'info': 'Writing code and stuff',
},
{'name': 'Gaming'},
],
}
"""
# 从列表对象中排除所有子元素的info属性
print(user.dict(exclude={'hobbies': {'__all__': {'info'}}}))
"""
{
'first_name': 'John',
'second_name': 'Doe',
'address': {
'post_code': 123456,
'country': {'name': 'USA', 'phone_code': 1},
},
'card_details': {
'number': SecretStr('**********'),
'expires': datetime.date(2020, 5, 1),
},
'hobbies': [{'name': 'Programming'}, {'name': 'Gaming'}],
}
"""
2.model.json(...)
-
法会将模型序列化为 JSON
-
encoder
:支持使用自定义的编码器函数 -
json_encoders
的使用(模型继承期间,它们也会合并,子编码器优先于父编码器)
from datetime import datetime, timedelta
from pydantic import BaseModel
from pydantic.json import timedelta_isoformat
class WithCustomEncoders(BaseModel):
dt: datetime
diff: timedelta
class Config:
json_encoders = {
# 参数类型:处理方法
datetime: lambda v: v.timestamp(),
timedelta: timedelta_isoformat,
}
m = WithCustomEncoders(dt=datetime(2032, 6, 1), diff=timedelta(hours=100))
print(m.json())
# {"dt": 1969660800.0, "diff": "P4DT4H0M0.000000S"}
models_as_dict=False
:模型作为字典序列化对象,是否进行序列化
from typing import List, Optional
from pydantic import BaseModel
class Address(BaseModel):
city: str
country: str
class User(BaseModel):
name: str
address: Address
friends: Optional[List['User']] = None
class Config:
json_encoders = {
# 将Address和User作为序列化对象
Address: lambda a: f'{a.city} ({a.country})',
'User': lambda u: f'{u.name} in {u.address.city} '
f'({u.address.country[:2].upper()})',
# "address": lambda a: f'{a.city} ({a.country})',
# 'friends': lambda u: f'{u.name} in {u.address.city} '
# f'({u.address.country[:2].upper()})',
}
wolfgang = User(
name='Wolfgang',
address=Address(city='Berlin', country='Deutschland'),
friends=[
User(name='Pierre', address=Address(city='Paris', country='France')),
User(name='John', address=Address(city='London', country='UK')),
],
)
# 对其进行序列化
print(wolfgang.json(models_as_dict=False))
"""
{"name": "Wolfgang", "address": "Berlin (Deutschland)", "friends": ["Pierre in Paris (FR)", "John in London (UK)"]}
"""
# 不对其进行序列化
print(wolfgang.json())
"""
{"name": "Wolfgang", "address": {"city": "Berlin", "country": "Deutschland"}, "friends": [{"name": "Pierre", "address": {"city": "Paris", "country": "France"}, "friends": null}, {"name": "John", "address": {"city": "London", "country": "UK"}, "friends": null}]}
"""