当要对数据对象进行序化列实例化的时候
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}`. The serializer ' 18 'field might be named incorrectly and not match ' 19 'any attribute or key on the `{instance}` instance. ' 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