• DRF源码-serializers


    class BaseSerializer(Field)

    """
    The BaseSerializer class provides a minimal class which may be used
    for writing custom serializer implementations.
    这个类提供一个最小化的类,可以用来写自定义的序列化实现
    
    Note that we strongly restrict the ordering of operations/properties
    that may be used on the serializer in order to enforce correct usage.
    序列化上会用到的操作/属性的顺序是被限制的,为了正确的使用
    
    In particular, if a `data=` argument is passed then:
    如果传递data=这个参数
    
    .is_valid() - Available.可用
    .initial_data - Available.可用
    .validated_data - Only available after calling `is_valid()`调用is_valid之后可用
    .errors - Only available after calling `is_valid()`
    .data - Only available after calling `is_valid()`
    
    If a `data=` argument is not passed then:
    一般来水不会传递data这个参数
    .is_valid() - Not available.
    .initial_data - Not available.
    .validated_data - Not available.
    .errors - Not available.
    .data - Available.
    """
    

      

        def __init__(self, instance=None, data=empty, **kwargs):    #初始化,传入instance参数(一个model class的实例)
            self.instance = instance    #instance给到self
            if data is not empty:
                self.initial_data = data
            self.partial = kwargs.pop('partial', False)     #将额外的字典参数中,partial,context给到self,如果没有,给出默认值
            self._context = kwargs.pop('context', {})
            kwargs.pop('many', None)    #将many这个key删除
            super().__init__(**kwargs)  #继承父类的其余属性
    

      

        # 对self.data属性函数化,为了加判断
        # 将instance转化为data
        @property
        def data(self):
            if hasattr(self, 'initial_data') and not hasattr(self, '_validated_data'):
                msg = (
                    'When a serializer is passed a `data` keyword argument you '
                    'must call `.is_valid()` before attempting to access the '
                    'serialized `.data` representation.
    '
                    'You should either call `.is_valid()` first, '
                    'or access `.initial_data` instead.'
                )
                raise AssertionError(msg)
    
            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):

        # 继承父类的data属性,然后调用ReturnDict函数返回
        @property
        def data(self):
            ret = super().data
            return ReturnDict(ret, serializer=self)
    

      

    app目录

    serializer.py

    # 创建serializers.Serializer的子类
    # 几个field是Fields.py里Field的几个子类
    class ColorsSerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        colors = serializers.CharField(max_length=10)
        def create(self, validated_data):
            return Colors.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            instance.colors = validated_data.get('colors', instance.colors)
            instance.save()
            return instance
    

    views.py

    def test(request):
        color = Colors(id=2,colors='red')       #color为一个xxx.models.Colors的instance
        print(color)                            #一个instance,由该model类的__str__(self)的返回值决定
        serializer = ColorsSerializer(instance=color)    #将这个instance传入序列化类,返回一个序列化实例
        print(serializer.data)                  # <class 'rest_framework.utils.serializer_helpers.ReturnDict'>
        print(type(serializer.data))            # {'id': 2, 'colors': 'red'}
        return HttpResponse('done')
    

      

    class ModelSerializer(Serializer):

        """
        A `ModelSerializer` is just a regular `Serializer`, except that:
    
        * A set of default fields are automatically populated.
        * A set of default validators are automatically populated.
        * Default `.create()` and `.update()` implementations are provided.
        *将自动填充一组默认字段。
        *将自动填充一组默认验证器。
        *提供了默认的`.create()`和`.update()`实现。elds
        The process of automatically determining a set of serializer fields
        based on the model fields is reasonably complex, but you almost certainly
        don't need to dig into the implementation.
    
        If the `ModelSerializer` class *doesn't* generate the set of fields that
        you need you should either declare the extra/differing fields explicitly on
        the serializer class, or simply use a `Serializer` class.
        如果“modelserializer”class没有生成所需字段,我应该在序列化类明确申明额外字段
        或者直接使用Serializer类
        """

     

        # Default `create` and `update` behavior...
        def create(self, validated_data):
            """
            We have a bit of extra checking around this in order to provide
            descriptive messages when something goes wrong, but this method is
            essentially just:
            我们在这里有一些额外的检查,为了当发生错误时可以提供一些可描述的信息。
            但这个方法,本质上就是:
                return ExampleModel.objects.create(**validated_data)
    
            If there are many to many fields present on the instance then they
            cannot be set until the model is instantiated, in which case the
            implementation is like so:
            如果实例中有多对对字段,需要以下实现:先把字段从validated_data pop出来,
                example_relationship = validated_data.pop('example_relationship')
                instance = ExampleModel.objects.create(**validated_data)
                instance.example_relationship = example_relationship
                return instance
    
            The default implementation also does not handle nested relationships.
            If you want to support writable nested relationships you'll need
            to write an explicit `.create()` method.
            """
            raise_errors_on_nested_writes('create', self, validated_data)
    
            # 在Meta嵌套类中的model属性
            ModelClass = self.Meta.model
    
            # Remove many-to-many relationships from validated_data.
            # They are not valid arguments to the default `.create()` method,
            # as they require that the instance has already been saved.
            # 把model类的字段信息给到info
            # 处理多对多字段
            info = model_meta.get_field_info(ModelClass)
            many_to_many = {}
            for field_name, relation_info in info.relations.items():
                if relation_info.to_many and (field_name in validated_data):
                    many_to_many[field_name] = validated_data.pop(field_name)
            # 表插入,返回到instance
            try:
                instance = ModelClass._default_manager.create(**validated_data)
            except TypeError:
                tb = traceback.format_exc()
                msg = (
                    'Got a `TypeError` when calling `%s.%s.create()`. '
                    'This may be because you have a writable field on the '
                    'serializer class that is not a valid argument to '
                    '`%s.%s.create()`. You may need to make the field '
                    'read-only, or override the %s.create() method to handle '
                    'this correctly.
    Original exception was:
     %s' %
                    (
                        ModelClass.__name__,
                        ModelClass._default_manager.name,
                        ModelClass.__name__,
                        ModelClass._default_manager.name,
                        self.__class__.__name__,
                        tb
                    )
                )
                raise TypeError(msg)
    
            # Save many-to-many relationships after the instance is created.
            if many_to_many:
                for field_name, value in many_to_many.items():
                    field = getattr(instance, field_name)
                    field.set(value)
    
            return instance
    

      

        # 在instance上设定每个属性,然后save
        def update(self, instance, validated_data):
            raise_errors_on_nested_writes('update', self, validated_data)
            info = model_meta.get_field_info(instance)
    
            # Simply set each attribute on the instance, and then save it.
            # Note that unlike `.create()` we don't need to treat many-to-many
            # relationships as being a special case. During updates we already
            # have an instance pk for the relationships to be associated with.
            m2m_fields = []
            for attr, value in validated_data.items():
                if attr in info.relations and info.relations[attr].to_many:
                    m2m_fields.append((attr, value))
                else:
                    setattr(instance, attr, value)
    
            instance.save()
    
            # Note that many-to-many fields are set after updating instance.
            # Setting m2m fields triggers signals which could potentialy change
            # updated instance and we do not want it to collide with .update()
            for attr, value in m2m_fields:
                field = getattr(instance, attr)
                field.set(value)
    
            return instance
    
        # Determine the fields to apply...
    

      

    app目录

    serializers.py

    class ColorsSerializer(serializers.ModelSerializer):
        class Meta:
            model = Colors
            fields = ('url', 'id', 'colors')
    

      

    views.py

    def test(request):
        color = Colors(id=2,colors='red')       
        print(color)                            
        serializer = ColorsSerializer(instance=color,context={'request': request})    
        print(serializer.data)                  
        print(type(serializer.data))         
        return HttpResponse('done')
    

      

     几种多表操作的field应用

    读取外键的某个字段

    # Clothes的color是外键,默认情况下,color字段会对应母表的主键,id。
    # 使用SlugRelatedField可以指向外键,slug_field表示获取哪个字段返回给color
    # 这里color这个属性就被重写了
    class ClothesSerializer(serializers.ModelSerializer):
        color = serializers.SlugRelatedField(queryset=Colors.objects.all(), slug_field='colors_cn')
        class Meta:
            model = Clothes
            fields = ('url', 'id', 'color', 'desc')
    

      

  • 相关阅读:
    PHP基础介绍
    day96
    day95
    day94
    day93
    day93之微信推送
    22个必须知道的css技巧
    利用Js或Css滤镜实现IE6中PNG图片半透明效果 IE6PNG妥妥的
    dedecms调用日期格式化形式大全
    innerHTML动态添加html代码和脚本兼容性问题处理方法
  • 原文地址:https://www.cnblogs.com/jabbok/p/11281953.html
Copyright © 2020-2023  润新知