zoukankan      html  css  js  c++  java
  • Django Restframework -序列化组件

    源码解读

    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)
    __init__

    参数:

    instance 

    data : 待反序列化数据,既用户提交的数据

    **kwargs  关键字参数

    做了哪些事情

    • 将instance数据赋值给对象属性instance
    • 如果用户传递了数据(data)将数据赋值给对象属性 self.initial_data 
    • partial
    • _context
    • pop many
    • 调用filed __init__方法
        def __new__(cls, *args, **kwargs):
            # We override this method in order to automagically create
            # `ListSerializer` classes instead when `many=True` is set.
            if kwargs.pop('many', False):
                return cls.many_init(*args, **kwargs)
            return super().__new__(cls, *args, **kwargs)
    
        @classmethod
        def many_init(cls, *args, **kwargs):
            """
            This method implements the creation of a `ListSerializer` parent
            class when `many=True` is used. You can customize it if you need to
            control which keyword arguments are passed to the parent, and
            which are passed to the child.
    
            Note that we're over-cautious in passing most arguments to both parent
            and child classes in order to try to cover the general case. If you're
            overriding this method you'll probably want something much simpler, eg:
    
            @classmethod
            def many_init(cls, *args, **kwargs):
                kwargs['child'] = cls()
                return CustomListSerializer(*args, **kwargs)
            """
            allow_empty = kwargs.pop('allow_empty', None)
            child_serializer = cls(*args, **kwargs)
            list_kwargs = {
                'child': child_serializer,
            }
            if allow_empty is not None:
                list_kwargs['allow_empty'] = allow_empty
            list_kwargs.update({
                key: value for key, value in kwargs.items()
                if key in LIST_SERIALIZER_KWARGS
            })
            meta = getattr(cls, 'Meta', None)
            list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
            return list_serializer_class(*args, **list_kwargs)
    __new__
        def to_internal_value(self, data):
            raise NotImplementedError('`to_internal_value()` must be implemented.')
    
        def to_representation(self, instance):
            raise NotImplementedError('`to_representation()` must be implemented.')
    
        def update(self, instance, validated_data):
            raise NotImplementedError('`update()` must be implemented.')
    
        def create(self, validated_data):
            raise NotImplementedError('`create()` must be implemented.')
    View Code

    需要子类自己实施的

    save方法

        def save(self, **kwargs):
            assert not hasattr(self, 'save_object'), (
                'Serializer `%s.%s` has old-style version 2 `.save_object()` '
                'that is no longer compatible with REST framework 3. '
                'Use the new-style `.create()` and `.update()` methods instead.' %
                (self.__class__.__module__, self.__class__.__name__)
            )
    
            assert hasattr(self, '_errors'), (
                'You must call `.is_valid()` before calling `.save()`.'
            )
    
            assert not self.errors, (
                'You cannot call `.save()` on a serializer with invalid data.'
            )
    
            # Guard against incorrect use of `serializer.save(commit=False)`
            assert 'commit' not in kwargs, (
                "'commit' is not a valid keyword argument to the 'save()' method. "
                "If you need to access data before committing to the database then "
                "inspect 'serializer.validated_data' instead. "
                "You can also pass additional keyword arguments to 'save()' if you "
                "need to set extra attributes on the saved model instance. "
                "For example: 'serializer.save(owner=request.user)'.'"
            )
    
            assert not hasattr(self, '_data'), (
                "You cannot call `.save()` after accessing `serializer.data`."
                "If you need to access data before committing to the database then "
                "inspect 'serializer.validated_data' instead. "
            )
    
            validated_data = dict(
                list(self.validated_data.items()) +
                list(kwargs.items())
            )
            if self.instance is not None:
                self.instance = self.update(self.instance, validated_data)
                assert self.instance is not None, (
                    '`update()` did not return an object instance.'
                )
            else:
                self.instance = self.create(validated_data)
                assert self.instance is not None, (
                    '`create()` did not return an object instance.'
                )
    
            return self.instance
    save方法

    作用:反序列时通过instance属性来判断执行创建操作和更新操作

    参数: **kwargs 接受N个关键字参数,并将关键字参数并入validate_data

    做了那些事

    • 将验证后的用户提交的数据(validated_data)和程序员调用save方法时传入的关键字参数合并,而后将合并后的数据重新赋值给validated_data属性
            validated_data = dict(
                list(self.validated_data.items()) +
                list(kwargs.items())
            )
    • 判断属性instance是否存在,如果存在调用update方法,否则调用create方法
            if self.instance is not None: 
                self.instance = self.update(self.instance, validated_data)
                assert self.instance is not None, (
                    '`update()` did not return an object instance.'
                )
            else:
                self.instance = self.create(validated_data)
                assert self.instance is not None, (
                    '`create()` did not return an object instance.'
                )
    
            return self.instance

    is_valid方法

    源码

        def is_valid(self, raise_exception=False):
            assert not hasattr(self, 'restore_object'), (
                'Serializer `%s.%s` has old-style version 2 `.restore_object()` '
                'that is no longer compatible with REST framework 3. '
                'Use the new-style `.create()` and `.update()` methods instead.' %
                (self.__class__.__module__, self.__class__.__name__)
            )
    
            assert hasattr(self, 'initial_data'), (
                'Cannot call `.is_valid()` as no `data=` keyword argument was '
                'passed when instantiating the serializer instance.'
            )
    
            if not hasattr(self, '_validated_data'):
                try:
                    self._validated_data = self.run_validation(self.initial_data)
                except ValidationError as exc:
                    self._validated_data = {}
                    self._errors = exc.detail
                else:
                    self._errors = {}
    
            if self._errors and raise_exception:
                raise ValidationError(self.errors)
    
            return not bool(self._errors)
    View Code

    作用:返回校验结果,如果校验成功返回True,否则返回False, 内部会将验证后的数据赋值给self_validated_data(验证失败则为空字典),错误赋值个self._errors(如果验证成功为空字典)

    参数:raise_exception 默认为false, 如果设置为True,如果验证失败会主动抛出异常

    逻辑:

    静态属性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
    View Code

    作用: 返回to_representation结果 如果是序列化,将instance属性数据传给to_representation,如果是反序列化 将validated_data传递给to_representation方法

    参数

    逻辑

    self.errors

    返回_errros错误,该属性有is_valid()方法获得

    self.validated_data

    返回_validated_data即验证后的数据,由is_valid()方法获得

  • 相关阅读:
    nodejs基础
    javscript基本语法
    棋牌游戏趟坑笔记20200617
    nodejs 简介
    python 安装pip
    棋牌游戏趟坑笔记 2020-06-16
    棋牌游戏趟坑笔记 2020-06-15
    linux下安装java环境--debian
    马克思主义学习第二章第一节
    马克思主义学习第一章
  • 原文地址:https://www.cnblogs.com/wc89/p/12730148.html
Copyright © 2011-2022 走看看