1、实例化字段对象
在创建类的时候,类里面定义的 类属性 和 方法是要比 类先创造的,因为如果我们用type()
这种方式创建类的时候,类属性和方法是要当作参数传给type的,所以 创建类的时候 类属性
和方法是先有的,然后再创建类
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import models
创建InfoSerializer之前,先实例化下面各个字段
class InfoSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField()
order = serializers.IntegerField()
对于上述代码,在类InfoSerializer
创建之前,其内部id、title、order
字段会先进行实例化对象。
而这些IntegerField
、CharField
等字段的继承关系如下:
class Field:
_creation_counter = 0
class IntegerField(Field):
pass
class CharField(Field):
pass
class DateTimeField(Field):
pass
在IntegerField
、CharField
等字段实例化时,内部会维护一个计数器,来表示实例化的先后顺序。比如密码确认,有两个密码,第一次输入密码,第二次确认密码,这个一定是有先后顺序的,所以当有的场景需要按先后顺序执行Field 维护_creation_counter 就有必要了
class Field:
_creation_counter = 0
def __init__(self, *, read_only=False...):
self._creation_counter = Field._creation_counter
Field._creation_counter += 1
class IntegerField(Field):
def __init__(self, **kwargs):
...
super().__init__(**kwargs)
class CharField(Field):
def __init__(self, **kwargs):
...
super().__init__(**kwargs)
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import models
class InfoSerializer(serializers.Serializer):
按照如下顺序实例化,_creation_counter 也依次递增,由_creation_counter
便可以决定以后的执行顺序
id = serializers.IntegerField() # 对象,内部_creation_counter=0
title = serializers.CharField() # 对象,内部_creation_counter=1
order = serializers.IntegerField # 对象,内部_creation_counter=2
注意:后续会通过这个计数器排序,以此来实现字段的先后执行。
2、序列化类的创建
如果父类指定了由特定的metaclass创建类,那么子类继承父类的时候,子类也是由父类的元类
创建,我们创建序列化类时候,会继承Serializer 或者 ModelSerializer 而 ModelSerializer
也是继承 Serializer,Serializer是由 SerializerMetaclass 元类创建类,所以序列化类也是由
SerializerMetaclass 创建的
创建序列化类时,首先走 SerializerMetaclass的 new 方法
class SerializerMetaclass(type):
# cls是指 SerializerMetaclass本身类(猜测,后面还需要确认)
# name 要创建类的类名
# bases 要创建类的父类
# attrs 类属性
def __new__(cls, name, bases, attrs):
attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
return super().__new__(cls, name, bases, attrs)
class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
...
class ModelSerializer(Serializer):
...
class RoleSerializer(serializers.ModelSerializer):
gender = serializers.CharField(source="get_gender_display")
class Meta:
model = models.Role
fields = ["id", 'title',"gender"