• 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}`.
    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
  • 相关阅读:
    Python--day68--ORM内容回顾
    Python--day67--include包含其他的url和反向解析URL
    Python--day67--Django的路由系统
    Python--day67--Jsonresponse响应介绍和路由系统的分组命名匹配方式(简单介绍)
    Python--day67--CBV和FBV、Request对象及上传文件示例
    Python--day66--Django模板语言关于静态文件路径的灵活写法
    GET和POST两种基本请求方法的区别
    ASP.NET中使用UpdatePanel实现局部异步刷新方法和攻略(转)
    GridView中实现DropDownList联动
    .NET string字符串的截取、移除、替换、插入
  • 原文地址:https://www.cnblogs.com/arrow-kejin/p/9992985.html
Copyright © 2020-2023  润新知