DRF 序列化类保存save源码

【七】序列化保存save源码

【1】介绍

  • 无论是创建还是修改数据,都需要执行save方法,再前面的使用中都没有再里面添加过参数
    • 其实save中可以给额外参数
    • 比如.save(time=datetime.datetime.now())
    • 这个需要模型表中有time的字段,结果就是将当前时间也保存在表中,不用经过数据校验

【2】需要的基础知识

(1)assert

  • assert 是 Python 中用于调试的一个关键字,它允许程序员在代码中设置检查点,以确保程序在运行时满足特定的条件。
    • 如果条件为真(True),则 assert 语句不会做任何事情,程序将继续执行。
    • 如果条件为假(False),assert 会引发一个 AssertionError 异常,通常还伴随着一个可选的错误消息,用于解释断言失败的原因。

(2)反射方法hastattr

  • hasattr 是 Python 的内置函数,用于检查对象是否具有特定的属性。

    • 这个函数接受两个参数:一个对象和一个字符串,该字符串表示要检查的属性名。
    • 如果对象具有该属性,hasattr 返回 True;否则,返回 False
  • 详情请见:Python 面向对象之反射_python对象反射-CSDN博客

(3)示例

class A:
    class_name = "A"

try:
    a = A()
    assert hasattr(a, 'class_name'), ('Don`t have class_name')
    assert hasattr(a, 'name'), ('Don`t have name')
except Exception as e:
    print(e)

# Don`t have name
  • 最外层用try来捕获异常,如果发现了异常那么就执行异常的输出print(e)
    1. 首先实例化一个对象a
    2. 然后使用两个断言,每个断言的前面是一个反射方法,对实例a进行属性的判断,
      • 在返回True,那么就不会执行断言后面的参数;
      • 不在返回False,那么会返回后面的报错描述信息

【3】分析源码

  • 这是序列化类的save方法源码
def save(self, **kwargs):
    assert hasattr(self, '_errors'), (...)
    assert not self.errors, (...)
    assert 'commit' not in kwargs, (...)
    assert not hasattr(self, '_data'), (...)

    validated_data = {**self.validated_data, **kwargs}

    if self.instance is not None:
        self.instance = self.update(self.instance, validated_data)
        assert self.instance is not None, ()
    else:
        self.instance = self.create(validated_data)
        assert self.instance is not None, ()

    return self.instance

image-20240414221839421

  • 首先执行了四个断言

    1. hasattr(self, '_errors'):检查对象是否有 _errors 属性。这个属性是在 .is_valid() 后设置的,如果没有说明没进行反序列化检查
    2. assert not self.errors:检查对象errors属性是否为空。有值说明数据检验不通过
    3. 'commit' not in kwargs防止用户错误地传递 'commit' 参数给 save() 方法,并提示用户正确的使用方式。
    4. not hasattr(self, '_data'):这个断言确保在访问 serializer.data 属性之后没有调用 .save() 方法。访问 serializer.data 通常意味着序列化器的数据已经被渲染成输出格式(如 JSON),此时再调用 .save() 可能会导致不一致或错误的状态
  • 重点来了validated_data = {**self.validated_data, **kwargs}

    • 首先validated_data这个是通过校验的所有数据,是普通的字典格式(querydict就不是普通字典格式),普通字典格式可以使用**进行打散,即{"name":"bruce"}将变成name=bruce,打散放在字典中
    • kwargs是就是我们自定义传进来的信息,同样的进行打散,放在通过校验的数据中,所以我们可以直接在save方法中进行传值
  • 接下来就是进行实例instance的判断

    • 没有实例instance,说明是创建实例,即调用create方法
    • 有实例instance,说明就是要修改操作,即调用update方法
  • 创建或修改完成后,同样通过断言 assert self.instance is not None, () 确保 self.instance 不是 None

    • 这也是一个安全检查,确保创建操作成功返回了一个实例。

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值