• 基于前一天再补充


    一. 单改(单整体改  put)

      整体思路,跟post一样,将数据进行反序列化,完成校验后,再做修改.

      重写update方法,bookser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data),验证通过返回ser_obj.validated_data,验证不通过返回ser_obj.errors.

      验证:单个字段的验证def validated_字段名称(self, value):

                  不通过raise ValidationError("错误信息")

                 通过 return attrs

         多个字段的验证:def validate(self, attrs)

                    attrs 是所有字段组成的字典

                   不通过 raise ValidationError('错误信息')

                    通过 return attrs

         自定义的验证:def my_validate(value):            

                  不通过 raise ValidationError('错误信息')

                    通过 return value

          配置:给字段加validators=[my_validate]

           

      视图层:

        def put(self, request, *args, **kwargs):
            request_data = request.data
            pk = kwargs.get('pk')
            old_book_obj = models.Book.objects.filter(pk=pk).first()
            # 目的: 将众多数据的校验交给序列化类来处理,让序列化类扮演反序列化角色,校验成功后,序列化来帮忙入库
            bookser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data)  # 得到一个序列化对象
            # raise_exception = True 当校验失败,马上返回视图方法,将反序列化校验中的error_message返回给前端
            bookser.is_valid(raise_exception=True)
            # 校验通过后,完成数据的更新: 要更新的目标,用来更新的新数据
            book_obj = bookser.save()
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': serializers.V2BookModelSerializer(book_obj).data
            })
    

      注意:

     1 1) 单整体改,说明前台要提供修改的数据,那么数据就需要校验,校验的数据应该在实例化“序列化类对象”时,赋值给data
     2 2)修改,就必须明确被修改的模型类对象,并在实例化“序列化类对象”时,赋值给instance
     3 3)整体修改,所有校验规则有required=True的字段,都必须提供,因为在实例化“序列化类对象”时,参数partial默认为False
     4 
     5 
     6 注:如果partial值设置为True,就是可以局部改
     7 1)单整体修改,一般用put请求:
     8 V2BookModelSerializer(
     9     instance=要被更新的对象, 
    10     data=用来更新的数据,
    11     partial=默认False,必须的字段全部参与校验
    12 )

    二. 单局部修改

      基于单增,只需在序列化时加partial = True

    def dispatch(self, request, *args, **kwargs):
            request_data = request.data
            pk = kwargs.get('pk')
            old_book_obj = models.Book.objects.filter(pk=pk).first()
            # 目的: 将众多数据的校验交给序列化类来处理,让序列化类扮演反序列化角色,校验成功后,序列化来帮忙入库
            bookser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data, partial=True)  # 得到一个序列化对象
            # raise_exception = True 当校验失败,马上返回视图方法,将反序列化校验中的error_message返回给前端
            bookser.is_valid(raise_exception=True)
            # 校验通过后,完成数据的更新: 要更新的目标,用来更新的新数据
            book_obj = bookser.save()
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': serializers.V2BookModelSerializer(book_obj).data
            })

      注意:

    单局部修改,一般用patch请求:
    V2BookModelSerializer(
        instance=要被更新的对象, 
        data=用来更新的数据,
        partial=设置True,必须的字段都变为选填字段
    )
        注:partial设置True的本质就是使字段 required=True 校验规则失效

    三. 单与整体局部修改

      序列化层: serializers.py

    # 重点:ListSerializer与ModelSerializer建立关联的是:
    # ModelSerializer的Meta类的 - list_serializer_class
    class V2BookListSerializer(ListSerializer):
        def update(self, instance, validated_data):
            # print(instance)  # 要更新的对象们
            # print(validated_data)  # 更新的对象对应的数据们
            # print(self.child)  # 服务的模型序列化类 - V2BookModelSerializer
            for index, obj in enumerate(instance):
                self.child.update(obj, validated_data[index])
            return instance
        
    # 原模型序列化类变化
    class V2BookModelSerializer(ModelSerializer):
        class Meta:
            # ...
            # 群改,需要设置 自定义ListSerializer,重写群改的 update 方法
            list_serializer_class = V2BookListSerializer
    

      视图层:

    class V2Book(APIView):
        # 单局部改:对 v2/books/(pk)/ 传的数据,数据字段key都是选填
        # 群局部改:对 v2/books/ 
        # 请求数据 - [{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}]
        def patch(self, request, *args, **kwargs):
            request_data = request.data
            pk = kwargs.get('pk')
    
            # 将单改,群改的数据都格式化成 pks=[要需要的对象主键标识] | request_data=[每个要修改的对象对应的修改数据]
            if pk and isinstance(request_data, dict):  # 单改
                pks = [pk, ]
                request_data = [request_data, ]
            elif not pk and isinstance(request_data, list): # 群改
                pks = []
                for dic in request_data:  # 遍历前台数据[{pk:1, name:123}, {pk:3, price:7}, {pk:7, publish:2}],拿一个个字典
                    pk = dic.pop('pk', None)  # 如果pk拿不到值,就拿None
                    if pk:
                        pks.append(pk)
                    else:
                        return Response({
                            'status': 1,
                            'msg': '数据有误',
                        })
            else:
                return Response({
                    'status': 1,
                    'msg': '数据有误',
                })
    
            # pks与request_data数据筛选,
            # 1)将pks中的没有对应数据的pk与数据已删除的pk移除,request_data对应索引位上的数据也移除
            # 2)将合理的pks转换为 objs
            objs = []
            new_request_data = []
            for index, pk in enumerate(pks):
                try:
                    # pk对应的数据合理,将合理的对象存储
                    obj = models.Book.objects.get(pk=pk)
                    objs.append(obj)
                    # 对应索引的数据就需要保存下来
                    new_request_data.append(request_data[index])
                except:
                    # 重点:反面教程 - pk对应的数据有误,将对应索引的data中request_data中移除
                    # index = pks.index(pk)
                    # request_data.pop(index)
                    continue
    
            book_ser = serializers.V2BookModelSerializer(instance=objs, data=new_request_data, partial=True, many=True)
            book_ser.is_valid(raise_exception=True)
            book_objs = book_ser.save()
    
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': serializers.V2BookModelSerializer(book_objs, many=True).data
            })
    生前无需久睡,死后自会长眠,努力解决生活中遇到的各种问题,不畏将来,勇敢面对,加油,你是最胖的,哈哈哈
  • 相关阅读:
    LoadRunner调用java函数测试oracle
    pam_cracklib.so模块
    crontab定时任务安装、使用方法
    yum的repo文件详解、以及epel简介、yum源的更换
    ubuntu添加开机自启和sysv-rc-conf
    MySQL配置参数详解
    集群管理软件clustershell
    Mysql命令大全
    Nginx配置文件nginx.conf 详解
    linux下iptables配置详解
  • 原文地址:https://www.cnblogs.com/panshao51km-cn/p/11696122.html
Copyright © 2020-2023  润新知