参考
- 参考
- pydantic是一个解析库,而不是一个验证库
- pydantic保证输出模型的类型和约束,而不是输入数据
BaseModel&属性类型&属性默认值
from pydantic.networks import HttpUrl
from apit import model
from sys import setcheckinterval
from typing import Generic, Mapping, Optional, TypeVar, Union
import json
from pydantic import BaseModel, Field, create_model, parse_obj_as
from pydantic.generics import GenericModel
from pydantic.class_validators import validator
from random import randint
# 模型示例
TA = TypeVar('TA')
TB = TypeVar('TB')
class A(GenericModel, Generic[TA, TB]): # 可泛型模型
gf_1: TA # 类型为泛型
gf_2: TB # 类型为泛型
A[str, int](gf_1=1, gf_2='') # 泛型还能这么玩,在创建实例的时候指定类型
class Demo(BaseModel): # 定义一个Model
id: int # ①定义模型属性;②没有定义默认值则为必传属性;③定义了type-hint则解析为type-hint类型
sex: int = 0 # ①定义模型属性;②定义了默认值则为非传属性;
name: str
a: Optional[A] = None # 非必传嵌套模型
json_: str = Field(alias='json') # 定义一个重名属性,并指定别名,指定的别名可以用于init和dict过程
must_1: Optional[int] # 必传,并且强制转换为int或None
must_2: Union[int] # 必传,并且强制转换为int类型
field_type: HttpUrl # 指定字段解析类型,支持typing类型,自定义类型,pydantic定义的一些类型
maps: Mapping[str, int]
field_1: int = Field( # Field是一个函数,用来创建一个FieldInfo对象
default=..., # 默认值为...表示为必传
default_factory=lambda : 1, # 通过方法获取默认值
alias='别名', # 属性名称冲突时可指定别名
description='描述', # 字段描述
# 数值范围
gt=1, # 大于
ge=2, # 大于等于
lt=10, # 小于
le=10, # 小于等于
# 字符串范围
max_length=10,
min_length=1,
# list范围
max_items=10,
min_items=1,
# 其它
allow_mutation=False, # 是否允许赋值
regex='' # 正则校验
)
@validator('maps', each_item=True) # 解析每一项,可以是dict/list/等
@classmethod
def valid_maps(cls, item): # 逐项解析
pass
@validator('name') # 指定解析的模型属性
@classmethod
def valid_name(cls, v: str): # 通过自定义类方法解析获取模型属性
v = v.strip()
if not 1 <= len(v) <= 100:
raise ValueError('1-100!') # 自定义错误内容
return v
class Config: # 模型配置
orm_mode = True # 开启orm模式,可以将复杂类型转化为基本类型
allow_mutation = False # 不允许在类外部重新赋值,默认是允许的
json_loads = json.loads # 指定序列化和反序列化方法
json_dumps = json.dumps
# 创建模型
demo_1 = Demo(id=1, name=2, sex=3) # 通过实例化创建一个模型实例,参数为模型属性
obj = {'id': 1, 'name': 2, 'sex': 3} # json的obj->python的dict
demo_2 = Demo.parse_obj(obj=obj) # 通过解析对象创建一个模型实例
demo_3 = Demo(**obj) # 通过解包对象传参
class SqlAlchemyDemo:pass # sqlalchemy定义的一个BaseModel
demo_4 = Demo.from_orm(SqlAlchemyDemo())# 模型开启ORM模式之后,可以在复杂对象中解析模型
# 模型类方法
json_schema: str = Demo.schema_json() # 从模型中获取json schema(json str形式)
schema: dict = Demo.schema() # 从模型中获取json schema(dict形式)
# 模型实例方法,导出模型
demo_1.dict() # 参数和json()的基本一致,只是返回类型不一样
demo_1.json(
include={'name'}, # 包含的字段
exclude={'id'}, # 不包含的字段,如去掉password
by_alias=True, # 使用别名
exclude_unset=True, # 不包含没有设置的属性
exclude_defaults=True, # 不包含等于默认值的属性
exclude_none=True, # 不高含为None的属性
encoder=lambda v: v, # 自定义一个编码函数,用于编码
indent=2 # 两层
)
demo_1.copy(
include={'id'}, # copy包含sex
exclude={'name'}, # copy不包含id
update={'id': 1}, # copy并将name改为zhangsan
deep=True # 深拷贝,默认为浅拷贝
)
# 反序列化:json/ujson/orjson