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的更多相关文章

  1. Django之DRF源码分析(二)---数据校验部分

    Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...

  2. [drf]源码和序列化梳理

    drf源码继承管理 # drf继承关系 View APIView as_view: 执行父类的as_view 调用dispatch dispatch init_request request.quer ...

  3. 02 drf源码剖析之快速了解drf

    02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...

  4. Django与drf 源码视图解析

    0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...

  5. drf源码save以及response

    drf源码save以及response 一.save 其中蛮重要的一段 if self.instance is not None: self.instance = self.update(self.i ...

  6. DRF源码系列分析

    DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流

  7. drf源码剖析系列(系列目录)

    drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...

  8. 07 drf源码剖析之节流

    07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...

  9. 06 drf源码剖析之权限

    06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...

随机推荐

  1. 初级入门 --- 认识 WebGL

    WebGL 是什么? WebGL 是一组基于 JavaScript 语言的图形规范,浏览器厂商按照这组规范进行实现,为 Web 开发者提供一套3D图形相关的 API. 这些 API 能够让 Web 开 ...

  2. Redis之datatype概述

    Redis支持的数据类型     String     List    Set    Sorted Set    Hashes    Bit array    HyperLogLog     Bina ...

  3. iplimage 转HBITMAP

    HBITMAP IplImage2hBitmap(IplImage* pImg) { cvFlip(pImg, NULL); BYTE tmp[]; BITMAPINFO *bmi = (BITMAP ...

  4. XV6源代码阅读-虚拟内存管理

    Exercise1 源代码阅读 1.内存管理部分: kalloc.c vm.c 以及相关其他文件代码 kalloc.c:char * kalloc(void)负责在需要的时候为用户空间.内核栈.页表页 ...

  5. Delphi IDFtp用法,包含断点续传

    1  连接远程服务器procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);2  改变目录procedure ChangeDir ...

  6. Centos 8下命令行界面支持鼠标

    yum install gpm* service gpm start systemctl enable gpm.service

  7. redis学习(五)

    一.Redis 发布订阅 1.Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 2.Redis 客户端可以订阅任意数量的频道. 比如你订阅 ...

  8. js 跳转链接

    1.跳转链接 在当前窗口打开 window.location.href="http://www.baidu.com" 等价于 <a href="baidu.com& ...

  9. mvn 编译报错mavn sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targ

    mavn 编译报错: mavn sun.security.validator.ValidatorException: PKIX path building failed: sun.security.p ...

  10. MongoDB 初始化数据同步

    MongoDB初始化数据同步: 副本集中的成员启动之后,就会检查自身的状态,确定是否可以从某个成员那里进行同步.如果不行的话,尝试从其他成员那里进行完整的数据复制. 这个过程就是初始化同步(initi ...