Django(44)drf序列化源码分析
2021-06-04 15:06
1131 查看
序列化与反序列化
一般后端数据返回给前端的数据格式都是
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) @classmethod def 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): @property def data(self): @property def errors(self) @property def validated_data(self)
我们分析几个重要的方法,没必要每个方法都了解,分析的都是后面要用到的
__init__方法
def __init__(self, instance=None, data=empty, **kwargs): self.instance = instance if data is not empty: self.initial_data = data self.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.detail else: 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_data assert 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_data self.instance = self.create(validated_data) assert self.instance is not None, ( '`create()` did not return an object instance.' ) return self.instance
相关文章推荐
- AFNetworking3.1.0源码分析(六)详解AFHTTPRequestSerializer 之序列化NSMutableURLRequest
- DRF Django REST framework 之 序列化(三)
- Django搭建及源码分析(三)---+uWSGI+nginx
- 深入学习Django源码基础9 - 简单分析DjangoORM部分
- 细水长流Hadoop源码分析(1)Hadoop序列化系统
- Django Signals实践与源码分析
- Django源码分析之执行入口
- Django rest framework源码分析(3)----节流
- Django rest framework源码分析(一) 认证
- Django源码分析--引导
- python django事务transaction源码分析详解
- django中间件CsrfViewMiddleware源码分析,探究csrf实现
- Django Signals 从实践到源码分析(转)
- 12.源码分析—如何为SOFARPC写一个序列化?
- drf 认证校验及源码分析
- django源码分析 -- django启动初始化过程分析
- Django源码分析1:创建项目和应用分析
- Django rest framework 权限操作(源码分析)
- django源码分析----Related继承结构
- Django Form源码分析之Field验证逻辑