AI智能
改变未来

Django(44)drf序列化源码分析


序列化与反序列化

  一般后端数据返回给前端的数据格式都是

json

格式,简单易懂,但是我们使用的语言本身并不是

json

格式,像我们使用的

Python

如果直接返回给前端,前端用的

javascript

语言是识别不出的,所以我们需要把

python

语言转换为通用的

json

格式的数据,在

django

中就是将

orm

模型或者

queryset

对象转换成字典,再由字典转换成

json

,整个过程就是序列化。

  当用户通过在

form

表单中填写的数据,发送请求给后端,将数据提交给后端数据库,这个过程就是反序列化。反序列化的时候,我们需要去验证前端提交的数据是否符合后端制定的规范,符合才进行入库。 

drf的序列化类

drf

的序列化类有3个

  • Serializer
  • ModelSerializer(使用最多的)
  • ListSerializer

我们使用最多的就是

ModelSerializer

,这三个序列化类都继承自

BaseSerializer

,虽然我们项目中99%都是使用的

ModelSerializer

,但是光知道怎么使用,是没有灵魂的,我们还需要去了解源码,多看源码能迅速提高代码能力。 

BaseSerializer

源码分析

源码如下:

class BaseSerializer(Field):def __init__(self, instance=None, data=empty, **kwargs):def __new__(cls, *args, **kwargs)def __class_getitem__(cls, *args, **kwargs)@classmethoddef many_init(cls, *args, **kwargs):def to_internal_value(self, data):def to_representation(self, instance):def update(self, instance, validated_data):def create(self, validated_data):def save(self, **kwargs):def is_valid(self, raise_exception=False):@propertydef data(self):@propertydef errors(self)@propertydef validated_data(self)

我们分析几个重要的方法,没必要每个方法都了解,分析的都是后面要用到的 

__init__方法

def __init__(self, instance=None, data=empty, **kwargs):self.instance = instanceif data is not empty:self.initial_data = dataself.partial = kwargs.pop(\'partial\', False)self._context = kwargs.pop(\'context\', {})kwargs.pop(\'many\', None)super().__init__(**kwargs)

初始化方法,有4个参数

  • self:本身自己
  • instance:实例,默认为
    None
  • data:数据,默认为
    empty
  • **kwargs:不定长字典 

create

def create(self, validated_data):raise NotImplementedError(\'`create()` must be implemented.\')

定义了一个

create

方法,参数为

validated_data

,方法抛出了一个异常,意思是

create

方法没有定义,如果要继承

BaseSerializer

,那就必须定义

create

方法,否则就会抛出异常 

update

def update(self, instance, validated_data):raise NotImplementedError(\'`update()` must be implemented.\')

定义了一个

update

方法,有2个参数

  • instance

    :实例,更新数据的时候,需要知道更新的是哪个实例化对象

  • validated_data

    :已验证的数据,前端传入的字段需要进行验证

此方法抛出了一个异常,意思是

update

方法没有定义,如果要继承

BaseSerializer

,那就必须定义

update

方法,否则就会抛出异常 

is_valid

def is_valid(self, raise_exception=False):# 如果self对象没有initial_data属性,那么将无法调用该方法,如果需要有initial_data,那么实例化对象必须传入data参数assert hasattr(self, \'initial_data\'), (\'Cannot call `.is_valid()` as no `data=` keyword argument was \'\'passed when instantiating the serializer instance.\')if not hasattr(self, \'_validated_data\'):try:self._validated_data = self.run_validation(self.initial_data)except ValidationError as exc:self._validated_data = {}self._errors = exc.detailelse:self._errors = {}if self._errors and raise_exception:raise ValidationError(self.errors)return not bool(self._errors)

这个方法是验证从前端传输过来的字段是否验证成功,如果我们的实例化对象没有传入

data

参数,将会无法调用

is_valid

,这个方法大多数用在反序列化的时候 

save

def save(self, **kwargs):# 调用save()方法前必须先调用is_valid()assert hasattr(self, \'_errors\'), (\'You must call `.is_valid()` before calling `.save()`.\')# 不能对无效的数据调用save()方法assert not self.errors, (\'You cannot call `.save()` on a serializer with invalid data.\')# 防止没有正确使用save方法# Guard against incorrect use of `serializer.save(commit=False)`assert \'commit\' not in kwargs, ("\'commit\' is not a valid keyword argument to the \'save()\' method. ""If you need to access data before committing to the database then ""inspect \'serializer.validated_data\' instead. ""You can also pass additional keyword arguments to \'save()\' if you ""need to set extra attributes on the saved model instance. ""For example: \'serializer.save(owner=request.user)\'.\'")# 访问serializer.data后就不能调用save方法了,如果你需要在提交到数据库之前访问数据,那么请使用serializer.validated_dataassert not hasattr(self, \'_data\'), ("You cannot call `.save()` after accessing `serializer.data`.""If you need to access data before committing to the database then ""inspect \'serializer.validated_data\' instead. ")# 创建已验证的数据对象validated_data = {**self.validated_data, **kwargs}# 如果instance不为空if self.instance is not None:# instance对象将更新为validated_data里的内容self.instance = self.update(self.instance, validated_data)assert self.instance is not None, (\'`update()` did not return an object instance.\')else:# 如果instance为空,那么则创建对象,对象的内容为validated_dataself.instance = self.create(validated_data)assert self.instance is not None, (\'`create()` did not return an object instance.\')return self.instance
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Django(44)drf序列化源码分析