django rest framework之序列化的源码流程剖析

当要对数据对象进行序化列实例化的时候

1     def __new__(cls, *args, **kwargs):
2         # We override this method in order to automagically create
3         # `ListSerializer` classes instead when `many=True` is set.
4         if kwargs.pop('many', False): #如果是QuerySet的时候
5             return cls.many_init(*args, **kwargs) #会调用ListSerializer
6         return super(BaseSerializer, cls).__new__(cls, *args, **kwargs)

当要对数据对象进行序列化的时候会调用到Serializer类中的to_representation方法

 1     def to_representation(self, instance):
 2         """
 3         Object instance -> Dict of primitive datatypes.
 4         """
 5         ret = OrderedDict() #生成有序字典
 6         fields = self._readable_fields  #获取在我们在Serializer中定义的字段(必须和models中的字段名和类型一样)
 7 
 8         for field in fields:
 9             try:
10                 attribute = field.get_attribute(instance) #获取字段的对象
11             except SkipField:
12                 continue
13 
14             # We skip `to_representation` for `None` values so that fields do
15             # not have to explicitly deal with that case.
16             #
17             # For related fields with `use_pk_only_optimization` we need to
18             # resolve the pk value.
19             check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
20             if check_for_none is None:
21                 ret[field.field_name] = None
22             else:
23                 ret[field.field_name] = field.to_representation(attribute) #封装字段的值(每个字段类型可能不同)
24 
25         return ret
 1     def get_attribute(self, instance):
 2         """
 3         Given the *outgoing* object instance, return the primitive value
 4         that should be used for this field.
 5         """
 6         try:
 7             return get_attribute(instance, self.source_attrs) #如果在字段的source中定义了如:role.name(外键)会被拆分成[role, name]
 8         except (KeyError, AttributeError) as exc:
 9             if self.default is not empty:
10                 return self.get_default()
11             if self.allow_null:
12                 return None
13             if not self.required:
14                 raise SkipField()
15             msg = (
16                 'Got {exc_type} when attempting to get a value for field '
17                 '`{field}` on serializer `{serializer}`.\nThe serializer '
18                 'field might be named incorrectly and not match '
19                 'any attribute or key on the `{instance}` instance.\n'
20                 'Original exception text was: {exc}.'.format(
21                     exc_type=type(exc).__name__,
22                     field=self.field_name,
23                     serializer=self.parent.__class__.__name__,
24                     instance=instance.__class__.__name__,
25                     exc=exc
26                 )
27             )
28             raise type(exc)(msg)
29 
30 def get_attribute(instance, attrs):
31     """
32     Similar to Python's built in `getattr(instance, attr)`,
33     but takes a list of nested attributes, instead of a single attribute.
34 
35     Also accepts either attribute lookup on objects or dictionary lookups.
36     """
37     for attr in attrs:
38         try:
39             if isinstance(instance, collections.Mapping):
40                 instance = instance[attr]
41             else:
42                 instance = getattr(instance, attr) #获取对象的属性(如果这个属性还是一个数据实例对象的话就会再次循环调用)
43         except ObjectDoesNotExist:
44             return None
45         if is_simple_callable(instance): #判断是不是一个函数
46             try:
47                 instance = instance()
48             except (AttributeError, KeyError) as exc:
49                 # If we raised an Attribute or KeyError here it'd get treated
50                 # as an omitted field in `Field.get_attribute()`. Instead we
51                 # raise a ValueError to ensure the exception is not masked.
52                 raise ValueError('Exception raised in callable attribute "{0}"; original exception was: {1}'.format(attr, exc))
53 
54     return instance

猜你喜欢

转载自www.cnblogs.com/arrow-kejin/p/9992985.html