问题描述
在日常开发中,我们会先将接口入参转为Pydantic的模型,做参数校验,然后调用json()方法输出为json数据保存到数据库中。正常情况下,模型中所有的key都会输出到json中,随着业务的增长,需要保存的数据会比较庞大。其实,我们可以精简下json数据,只保留有效数据。
举个例子,有个模型包含了switch开关字段,当开关开启,所有字段都保留在json中;开关关闭,除了switch字段都不保留在json中。
实现方法
通过重写BaseModel的dict方法,我们实现了调用dict()和调用json()的时候,只返回需要保留的字段
import unittest
from typing import Optional
from pydantic import BaseModel, conint
class MyTestCase(unittest.TestCase):
def test_ignore(self):
class UserModel(BaseModel):
"""
继承SwitchModel
"""
# 功能开关
switch: conint(strict=True, ge=0, le=1)
name: str
phone: Optional[str]
def dict(self, **kwargs):
"""
定制pydantic库BaseModel的dict方法,确保switch=0时,只返回switch key;switch=1时,返回所有key
注意:
1.该dict方法会在pydantic库BaseModel的json方法调用,故json方法也会有一样的逻辑
"""
if self.switch == 0:
return super().dict(include={'switch'}) # 只保留switch key
return super().dict() # 保留所有key
class Test(BaseModel):
"""
使用嵌套模型验证
"""
# 【有效用法】使用对象做初始化,可以在dict()和json()调用实现只保留switch字段功能
model_switch_off: UserModel = UserModel(switch=0, name="a", phone="g") # 开关关闭
model_switch_on: UserModel = UserModel(switch=1, name="a", phone="g") # 开关开启
test = Test()
self.assertEqual(test.dict(), {
'model_switch_off': {'switch': 0}, # 开关关闭,其他字段删除
'model_switch_on': {'switch': 1, 'name': 'a', 'phone': 'g'},
}, msg='模型转字典比较失败')
self.assertEqual(test.json(),
'{'
'"model_switch_off": {"switch": 0}, ' # 开关关闭,其他字段删除
'"model_switch_on": {"switch": 1, "name": "a", "phone": "g"}}'
, msg="模型序列化为json比较失败")
self.assertEqual(test.model_switch_off.name, "a") # 开关关闭,模型的key实际还存在
self.assertEqual(test.model_switch_on.name, "a")