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. spring core:@AliasFor的派生性

    spring对Annotation的派生性应用可谓炉火纯青,在spring core:@Component的派生性讲过支持层次上派生性,而属性上派生的需求则借助了@AliasFor,它是从spring ...

  2. manjaro更换深度桌面 卸载ked桌面

    下载需要的桌面环境 pacman -S deepin deepin-extra 修改/etc/lightdm/lightdm.conf sudo nano /etc/lightdm/lightdm.c ...

  3. sql 报错问题

    SQLServer数据库密码已过期问题 处理

  4. js数据类型 判断

    1. js数据类型(两种数据类型) 基本数据类型:null undefined number boolean symbol string 引用数据类型: array object null: 空对象 ...

  5. c++链接mysql5.7

    1.单独安装mysql5.7 phpstudy安装的没有include和lib文件夹2.vs2013中右键属性 项目 - C/C++ - 常规 - 附加包含目录 里面添加 D:\**\include ...

  6. 四十七、在SAP中,把功能区块整合成一个函数,通过调用函数的办法使代码简洁明了

    一.我们查看上一次的代码,非常之凌乱,大体可以分为以下这几个区块 二.我们把最后的2个部分,用函数的方式来写,写法如下: 三.执行程序,和之前一样 四.输出结果

  7. servlet中调用注入spring管理的dao(转)

    今天做大型仪器的的时候遇到的问题,转下为了以后能用 http://blog.csdn.net/jiyingying_up/article/details/44803585 我们用spring的依赖注入 ...

  8. segger rtt 输出 log

    调试 mcu 的时候,使用 jlink 的 rtt 可以方便的输出信息. 输出有两种模式, client 和 logger. client 必须依附其他程序,比如说 mdk 调试状态,或者 logge ...

  9. crontab 实现Linux系统上定时任务的关键命令

    附上原文链接 https://www.cnblogs.com/ftl1012/p/crontab.html 原文真是写得非常好,所谓他山之石可以攻玉~,我就不客气啦,哈哈

  10. 经典SQL50句

    50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,T ...