zoukankan      html  css  js  c++  java
  • drf4

    单整体改

    单整体改:改的数据交给序列化类处理,根据源码得知,只要是数据都传给data;只要是对象都传给instance,而不写instance默认就传给它。

    路由层、模型层、序列化层不需要做修改,只需要处理视图层:views.py

    1)单整体修改:
        V2BookModelSerializer(
            instance=要被更新的对象, 
            data=用来更新的数据,
            partial=默认False,必须的字段全部参与校验
        )
    

    save中有create和update的方法,这些取决于instance的有无值

    • ​ (如果数据不传给data,则会报错提示)

    • ​ (data和instance)

    # 单整体改: 对 v2/books/(pk)/ 传的数据是与model对应的字典{name|price|publish|authors}
        def put(self, request, *args, **kwargs):
            request_data = request.data
            pk = kwargs.get('pk')
            old_book_obj = models.Book.objects.filter(pk=pk).first()
            # 目的:将众多数据的校验交给序列化类来处理 - 让序列化类扮演反序列化角色,校验成功后,序列化类来帮你入库
            book_ser = serializers.V2BookModelSerializer(instance=old_book_obj, data=request_data, partial=False)
            book_ser.is_valid(raise_exception=True)
            # 校验通过,完成数据的更新:要更新的目标,用来更新的新数据
            book_obj = book_ser.save()
    
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': serializers.V2BookModelSerializer(book_obj).data
            })
    

    单局部改:

    加一个partical=True

    2)单局部修改:
    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
        # ...
    
    视图层:views.py
    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)
                    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
            })
    

    可能的补充:

            # pks与request_data数据筛选,
            # 1)将pks中的没有对应数据的pk与数据已删除的pk移除,request_data对应索引位上的数据也移除。
            #    使用get搜索数据库,不存在的就通过异常处理,给处理掉
            # 2)将合理的pks转换为 objs
            objs = []
            new_request_data = []
            for index, pk in enumerate(pks):  # 【1,3,5,7,9】
                print('index,pk',index,pk)
                #1,1   ,2,3   ,3,5
                try:## {pk:1, name:123},{pk:3, price:7},{pk:7, publish:2}
                    # 取出点的v,通过for循环的索引值
                    # 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': 'ok1',
                'results': serializers.V2BookModelSerializer(book_objs, many=True).data
            })
    
    

    群改:需要手动updata方法


  • 相关阅读:
    HashMap 常问的 9 个问题
    P1855 榨取kkksc03
    Codeforces Round #697 (Div. 3) A. Odd Divisor
    P1474 [USACO2.3]Money System / [USACO07OCT]Cow Cash G
    Codeforces Round #704 (Div. 2) D. Genius's Gambit
    P2800 又上锁妖塔
    P2066 机器分配
    P3399 丝绸之路
    P1351 [NOIP2014 提高组] 联合权值
    P4290 [HAOI2008]玩具取名
  • 原文地址:https://www.cnblogs.com/ZDQ1/p/11694684.html
Copyright © 2011-2022 走看看