DRF源码-serializers
class BaseSerializer(Field)
"""
The BaseSerializer class provides a minimal class which may be used
for writing custom serializer implementations.
这个类提供一个最小化的类,可以用来写自定义的序列化实现 Note that we strongly restrict the ordering of operations/properties
that may be used on the serializer in order to enforce correct usage.
序列化上会用到的操作/属性的顺序是被限制的,为了正确的使用 In particular, if a `data=` argument is passed then:
如果传递data=这个参数 .is_valid() - Available.可用
.initial_data - Available.可用
.validated_data - Only available after calling `is_valid()`调用is_valid之后可用
.errors - Only available after calling `is_valid()`
.data - Only available after calling `is_valid()` If a `data=` argument is not passed then:
一般来水不会传递data这个参数
.is_valid() - Not available.
.initial_data - Not available.
.validated_data - Not available.
.errors - Not available.
.data - Available.
"""
def __init__(self, instance=None, data=empty, **kwargs): #初始化,传入instance参数(一个model class的实例)
self.instance = instance #instance给到self
if data is not empty:
self.initial_data = data
self.partial = kwargs.pop('partial', False) #将额外的字典参数中,partial,context给到self,如果没有,给出默认值
self._context = kwargs.pop('context', {})
kwargs.pop('many', None) #将many这个key删除
super().__init__(**kwargs) #继承父类的其余属性
# 对self.data属性函数化,为了加判断
# 将instance转化为data
@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):
self._data = self.to_representation(self.validated_data)
else:
self._data = self.get_initial()
return self._data
class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
# 继承父类的data属性,然后调用ReturnDict函数返回
@property
def data(self):
ret = super().data
return ReturnDict(ret, serializer=self)
app目录
serializer.py
# 创建serializers.Serializer的子类
# 几个field是Fields.py里Field的几个子类
class ColorsSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
colors = serializers.CharField(max_length=10)
def create(self, validated_data):
return Colors.objects.create(**validated_data) def update(self, instance, validated_data):
instance.colors = validated_data.get('colors', instance.colors)
instance.save()
return instance
views.py
def test(request):
color = Colors(id=2,colors='red') #color为一个xxx.models.Colors的instance
print(color) #一个instance,由该model类的__str__(self)的返回值决定
serializer = ColorsSerializer(instance=color) #将这个instance传入序列化类,返回一个序列化实例
print(serializer.data) # <class 'rest_framework.utils.serializer_helpers.ReturnDict'>
print(type(serializer.data)) # {'id': 2, 'colors': 'red'}
return HttpResponse('done')
class ModelSerializer(Serializer):
"""
A `ModelSerializer` is just a regular `Serializer`, except that: * A set of default fields are automatically populated.
* A set of default validators are automatically populated.
* Default `.create()` and `.update()` implementations are provided.
*将自动填充一组默认字段。
*将自动填充一组默认验证器。
*提供了默认的`.create()`和`.update()`实现。elds
The process of automatically determining a set of serializer fields
based on the model fields is reasonably complex, but you almost certainly
don't need to dig into the implementation. If the `ModelSerializer` class *doesn't* generate the set of fields that
you need you should either declare the extra/differing fields explicitly on
the serializer class, or simply use a `Serializer` class.
如果“modelserializer”class没有生成所需字段,我应该在序列化类明确申明额外字段
或者直接使用Serializer类
"""
# Default `create` and `update` behavior...
def create(self, validated_data):
"""
We have a bit of extra checking around this in order to provide
descriptive messages when something goes wrong, but this method is
essentially just:
我们在这里有一些额外的检查,为了当发生错误时可以提供一些可描述的信息。
但这个方法,本质上就是:
return ExampleModel.objects.create(**validated_data) If there are many to many fields present on the instance then they
cannot be set until the model is instantiated, in which case the
implementation is like so:
如果实例中有多对对字段,需要以下实现:先把字段从validated_data pop出来,
example_relationship = validated_data.pop('example_relationship')
instance = ExampleModel.objects.create(**validated_data)
instance.example_relationship = example_relationship
return instance The default implementation also does not handle nested relationships.
If you want to support writable nested relationships you'll need
to write an explicit `.create()` method.
"""
raise_errors_on_nested_writes('create', self, validated_data) # 在Meta嵌套类中的model属性
ModelClass = self.Meta.model # Remove many-to-many relationships from validated_data.
# They are not valid arguments to the default `.create()` method,
# as they require that the instance has already been saved.
# 把model类的字段信息给到info
# 处理多对多字段
info = model_meta.get_field_info(ModelClass)
many_to_many = {}
for field_name, relation_info in info.relations.items():
if relation_info.to_many and (field_name in validated_data):
many_to_many[field_name] = validated_data.pop(field_name)
# 表插入,返回到instance
try:
instance = ModelClass._default_manager.create(**validated_data)
except TypeError:
tb = traceback.format_exc()
msg = (
'Got a `TypeError` when calling `%s.%s.create()`. '
'This may be because you have a writable field on the '
'serializer class that is not a valid argument to '
'`%s.%s.create()`. You may need to make the field '
'read-only, or override the %s.create() method to handle '
'this correctly.\nOriginal exception was:\n %s' %
(
ModelClass.__name__,
ModelClass._default_manager.name,
ModelClass.__name__,
ModelClass._default_manager.name,
self.__class__.__name__,
tb
)
)
raise TypeError(msg) # Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
field = getattr(instance, field_name)
field.set(value) return instance
# 在instance上设定每个属性,然后save
def update(self, instance, validated_data):
raise_errors_on_nested_writes('update', self, validated_data)
info = model_meta.get_field_info(instance) # Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
m2m_fields = []
for attr, value in validated_data.items():
if attr in info.relations and info.relations[attr].to_many:
m2m_fields.append((attr, value))
else:
setattr(instance, attr, value) instance.save() # Note that many-to-many fields are set after updating instance.
# Setting m2m fields triggers signals which could potentialy change
# updated instance and we do not want it to collide with .update()
for attr, value in m2m_fields:
field = getattr(instance, attr)
field.set(value) return instance # Determine the fields to apply...
app目录
serializers.py
class ColorsSerializer(serializers.ModelSerializer):
class Meta:
model = Colors
fields = ('url', 'id', 'colors')
views.py
def test(request):
color = Colors(id=2,colors='red')
print(color)
serializer = ColorsSerializer(instance=color,context={'request': request})
print(serializer.data)
print(type(serializer.data))
return HttpResponse('done')
几种多表操作的field应用
读取外键的某个字段
# Clothes的color是外键,默认情况下,color字段会对应母表的主键,id。
# 使用SlugRelatedField可以指向外键,slug_field表示获取哪个字段返回给color
# 这里color这个属性就被重写了
class ClothesSerializer(serializers.ModelSerializer):
color = serializers.SlugRelatedField(queryset=Colors.objects.all(), slug_field='colors_cn')
class Meta:
model = Clothes
fields = ('url', 'id', 'color', 'desc')
DRF源码-serializers的更多相关文章
- Django之DRF源码分析(二)---数据校验部分
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
- [drf]源码和序列化梳理
drf源码继承管理 # drf继承关系 View APIView as_view: 执行父类的as_view 调用dispatch dispatch init_request request.quer ...
- 02 drf源码剖析之快速了解drf
02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...
- Django与drf 源码视图解析
0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...
- drf源码save以及response
drf源码save以及response 一.save 其中蛮重要的一段 if self.instance is not None: self.instance = self.update(self.i ...
- DRF源码系列分析
DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
- 07 drf源码剖析之节流
07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...
- 06 drf源码剖析之权限
06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...
随机推荐
- SQLyog连接报错 Error No.2058 Plugin caching_sha2_password could not be loaded
参考链接:https://blog.csdn.net/qq_22766431/article/details/80628583 win10系统更新安装Mysql8.0,连接SQLyog的时候出现下面错 ...
- ArrayList和LinkedList、Vector的优缺点?
一般在面试中可能会被问到ArrayList.LinkedList.Vector三者相关的区别! 一般来说我想大概都会回答如下的这些: ArrayList底层是数组结构,查询快,增删慢,线程不安全,效率 ...
- DB2的常用指令
注:大写的是固定的,小写的根据自己的实际情况 首先进入 命令窗口, win+r ---> 输入 db2cmd db2 1. 删除数据库 UNCATALOG DB db_name --db_nam ...
- Java常考面试题(二)(转)
序言 昨天刚开始的"每日5题面试"这类文章,感觉还不错,把一些平常看似懂了的东西,弄清楚了.就像什么是虚拟机?这个问题,看起来知道,但是要说出个所以然来,又懵逼了,经常回过头来看看 ...
- PHPXhprof扩展在windows安装
1.下载在这里 http://dev.freshsite.pl/php-extensions/xhprof.html.(找不到资源可以私我我给你,这个上传不了资源) 注意:一定要找对应的php版本,t ...
- python爬虫破解带有RSA.js的RSA加密数据的反爬机制
前言 同上一篇的aes加密一样,也是偶然发现这个rsa加密的,目标网站我就不说了,保密. 当我发现这个网站是ajax加载时: 我已经习以为常,正在进行爬取时,发现返回为空,我开始用findler抓包, ...
- 014-查看PHP的环境变量
<?php print("你正在用文件的名字为: "); print(__FILE__); print(" <BR>\n"); print(& ...
- NoSql相关
1 NoSQL, No Problem: An Intro to NoSQL Databases https://www.thoughtworks.com/insights/blog/nosql-n ...
- mysql数据库可视化工具—Navicat Premium—安装与激活
一.Navicat premium简介 Navicat premium是一款数据库管理工具.将此工具连接数据库,你可以从中看到各种数据库的详细信息.包括报错,等等.当然,你也可以通过他,登陆数据库,进 ...
- GNS3 ip route 命令解析
ip route 120.94.0.0 255.254.0.0 172.16.252.1ip route 192.168.0.0 255.255.0.0 10.10.10.119ip route 21 ...