使用序列化的代码
- 编写自定义Serializers类
class Media(models.Model):
TYPE_CHOICES = (
(1, "pic"),
(2, "video")
)
type = models.IntegerField(verbose_name='类型', choices=TYPE_CHOICES, default=1)
url = models.CharField(verbose_name='图片', max_length=64)
class MediaSerializers(serializers.ModelSerializer):
class Meta:
model = Media
fields = '__all__'
- 数据库拿到的数据序列化
queryset = Media.objects.all()
ser_obj = MediaSerializers(page_data, many=True)
ser_obj.data
分析
入口
1.我们先进行了实例化自定义的MediaSerializers类,生成一个对象。 看源码存在类实例化对象,重点关注该类和其父类中的__new__ 方法,其返回的是什么类的对象,就会调用该对象的__init__ 进行初始化对象。
在BaseSerializer 类中找到__init__ 和__new__ ,python中一个类实例化对象,会先执行该类的__new__ 方法。
class BaseSerializer(Field):
def __init__(self, instance=None, data=empty, **kwargs):
self.instance = instance
if data is not empty:
self.initial_data = data
self.partial = kwargs.pop('partial', False)
self._context = kwargs.pop('context', {})
kwargs.pop('many', None)
super().__init__(**kwargs)
def __new__(cls, *args, **kwargs):
if kwargs.pop('many', False):
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)
2.分析单个对象的序列化,序列化的入口是ser_obj.data
class BaseSerializer(Field):
@property
def data(self):
...
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):
def to_representation(self, instance):
"""
Object instance -> Dict of primitive datatypes.
"""
ret = OrderedDict()
fields = self._readable_fields
for field in fields:
try:
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:
ret[field.field_name] = field.to_representation(attribute)
return ret
class Field:
def get_attribute(self, instance):
try:
return get_attribute(instance, self.source_attrs)
def get_attribute(instance, attrs):
for attr in attrs:
try:
if isinstance(instance, Mapping):
instance = instance[attr]
else:
instance = getattr(instance, attr)
except ObjectDoesNotExist:
return None
if is_simple_callable(instance):
try:
instance = instance()
except (AttributeError, KeyError) as exc:
raise ValueError('Exception raised in callable attribute "{}"; original exception was: {}'.format(attr, exc))
return instance
|