RestFramework之序列化器源码解析
一.源码解析之序列化:
1.当视图类进行实例化序列化类做了如下操作:
#ModelSerializer继承Serializer再继承BaseSerializer(此类定义实例化方法)
#在BaseSerializer执行__new__方法,用于判断many是为True还是False:
class BaseSerializer:
def __new__(cls, *args, **kwargs):
if kwargs.pop('many', False):
#many = True, 对QuerySet进行处理
return cls.many_init(*args, **kwargs)
#many = False 对对象进行处理, 然后执行初始化方法__init__
return super().__new__(cls, *args, **kwargs)
#当many=True:为QuerySet对象,用ListSerializer进行处理
#当many=False:为单个对象,用Serializer进行处理
- 当
many=True,执行ListSerializer中to_representation方法。 对于数据展示,一直调用ListSerializer
class ListSerializer
def to_representation(self, data):
iterable = data.all() if isinstance(data, models.Manager) else data
return [
#循环每一个数据库的对象,再根据每一个对象,去调用它的每个字段的to_representation来做显示
self.child.to_representation(item) for item in iterable
]
- 当
many=False,执行自己Serializer
#当执行自己Serializer
class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
@property
def data(self):
#去父类执行data函数(父类BaseSerializer)
ret = super().data
#封装有序字典
return ReturnDict(ret, serializer=self)
#--------------------------------------------------------------------------
class BaseSerializer:
@property
def data(self):
if hasattr(self, 'initial_data') and not hasattr(self, '_validated_data'):
msg = (
'When a serializer is passed a `data` keyword argument you '
'must call `.is_valid()` before attempting to access the '
'serialized `.data` representation.\n'
'You should either call `.is_valid()` first, '
'or access `.initial_data` instead.'
)
raise AssertionError(msg)
if not hasattr(self, '_data'):
if self.instance is not None and not getattr(self, '_errors', None):
self._data = self.to_representation(self.instance)
elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
#执行to_representation,自己类中定义了此方法,去自己类中执行
self._data = self.to_representation(self.validated_data)
else:
self._data = self.get_initial()
return self._data
#--------------------------------------------------------------------------
class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
def to_representation(self, instance):
ret = OrderedDict()
fields = self._readable_fields
#遍历循环每个field字段。field为我们序列化器写的每个字段。
#序列化器中定义每个字段帮助我们去数据库里面把数据库字段拿取过来,通过Charfield,Interfield等类进行展示
for field in fields:
try:
#去数据库中获取指定字段对应值
#比如:
#当filed为id, 此时attribute=1
#当filed为pwd, 此时attribute=123
#如果设置特殊字段如:HyperlinkedIdentityField,它只会把当前字段对象取出来:obj
attribute = field.get_attribute(instance)
except SkipField:
continue
check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
if check_for_none is None:
ret[field.field_name] = None
else:
#相当于:
"""
{
id:1, CharField
pwd:123, CharField
group:obj, HyperlinkedIdentityField
}
"""
#通过每个字段类型再执行to_representation,
#因为有些字段一次无法拿到对应的值,所以,再通过各个字段的方法,如
#id:1 Charfield
#会执行field.to_representation(attribute) === Charfield.to_representation(1)
#Charfield中to_representation方法return six.text_type(value) === return str(value)
#而HyperlinkedIdentityField 执行to_representation,用反射方法去数据库找lookup_filed设置的字段,去数据库拿值,然后根据咱们之前设置好的look_url_kwargs的值(此值为url路由上设置动态参数名字)。然后通过这2个值通过reverse反向生成url.
ret[field.field_name] = field.to_representation(attribute)
return ret
- 未完待续,还差校验...
RestFramework之序列化器源码解析的更多相关文章
- springMVC 拦截器源码解析
前言:这两天学习了代理模式,自然想到了 springmvc 的 aop 使用的就是动态代理,拦截器使用的就是 jdk 的动态代理.今天看了看源码,记录一下.转载请注明出处:https://www.cn ...
- DRF之解析器源码解析
解析器 RESTful一种API的命名风格,主要因为前后端分离开发出现前后端分离: 用户访问静态文件的服务器,数据全部由ajax请求给到 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己 ...
- Struts2 源码分析-----拦截器源码解析 --- ParametersInterceptor
ParametersInterceptor拦截器其主要功能是把ActionContext中的请求参数设置到ValueStack中,如果栈顶是当前Action则把请求参数设置到了Action中,如果栈顶 ...
- MYSQL 优化器 源码解析
http://www.unofficialmysqlguide.com/introduction.html https://dev.mysql.com/doc/refman/8.0/en/explai ...
- Django:RestFramework之-------序列化器
8.序列化 功能: 对请求数据进行验证 对Queryset进行序列化 8.1一个简单序列化: import json from api import models from rest_framewor ...
- AQS源码解析(一)-AtomicBoolean源码解析
基本类: AtomicInteger AtomicLong AtomicBoolean 数组类型: AtomicIntegerArray AtomicLongArray AtomicReference ...
- 集合-ArrayList 源码解析
ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可称之为动态数组. 类图 ArrayList实现了List, RandomAccess, Cloneable, j ...
- [源码解析] PyTorch 分布式(14) --使用 Distributed Autograd 和 Distributed Optimizer
[源码解析] PyTorch 分布式(14) --使用 Distributed Autograd 和 Distributed Optimizer 目录 [源码解析] PyTorch 分布式(14) - ...
- [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器
[源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 目录 [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 0x0 ...
随机推荐
- md5加密后不能解密
MD5加密原理是散列算法,散列算法也称哈希算法.计算机专业学的数据结构就有哈希表这一知识点.比如10除以3余数为一,4除以3余数也为一,但余数为一的就不知道这个数是哪个了.所以md5不能解密.就算是设 ...
- Redis采坑(一)——数据无法插入,内存溢出
一.采坑背景 在最大数据分析的过程中,redis是被当做热数据的缓存库使用的,在某一天中,redis数据库热数据无法插入,此时数据量大概在100万左右,很是纠结,为什么不能插入?程序的错误,不可能,没 ...
- Arcgis案例操作教程——去掉Z值和M值
Arcgis案例操作教程--去掉Z值和M值 商务合作,科技咨询,版权转让:向日葵,135-4855__4328,xiexiaokui#qq.com 处理前 处理后: 处理方法 商务合作,科技咨 ...
- (九)Knockout 进一步技术
加载和保存 JSON 数据 Knockout允许您实现复杂的客户端交互,但是几乎所有web应用程序还需要与服务器交换数据,或者至少要序列化数据以供本地存储.交换或存储数据最方便的方式是JSON格式-- ...
- 相位展开(phase unwrapping)算法研究与实践
1. 什么是相位展开? 相位展开(Phase Unwrapping)是一个经典的信号处理问题,它指的是从值区间中恢复原始相位值(原因在于:计算相位时,运用反正切函数,则相位图中提取的相位都是包裹在一个 ...
- 【err】tensorflow.python.framework.errors_impl.OutOfRangeError: RandomShuffleQueue
problem Traceback (most recent call last): File , in _do_call return fn(*args) File , in _run_fn opt ...
- [LeetCode] 34. Search for a Range 搜索一个范围(Find First and Last Position of Element in Sorted Array)
原题目:Search for a Range, 现在题目改为: 34. Find First and Last Position of Element in Sorted Array Given an ...
- [LeetCode] 624. Maximum Distance in Arrays 数组中的最大距离
Given m arrays, and each array is sorted in ascending order. Now you can pick up two integers from t ...
- 开源之路2--SSH
SSH 为 Secure Shell (安全外壳协议)的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH是每一台Linux电脑的标准配置. SSH 是建立在应 ...
- mysql在windows下的服务安装
前提必须用管理员身份运行 1.删除Mysql服务,打开命令行,输入下面的指令 sc delete MySql 2.初始化一下数据,比如配置文件中设置了数据的存储路径,日志位置等:该命令必须用管理员身份 ...