searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Pydantic定制json方法实现忽略字段功能

2023-11-01 01:28:54
47
0

问题描述

在日常开发中,我们会先将接口入参转为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")

 

 

0条评论
0 / 1000
danceCode
5文章数
0粉丝数
danceCode
5 文章 | 0 粉丝
原创

Pydantic定制json方法实现忽略字段功能

2023-11-01 01:28:54
47
0

问题描述

在日常开发中,我们会先将接口入参转为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")

 

 

文章来自个人专栏
技术介绍
5 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0