批量增删改查

批量查询:

    def get(self,request,*args,**kwargs):
        # 查一个
        pk = kwargs.get('pk')
        if pk:
            book_list = models.Book.objects.filter(pk=pk).first()
            book_list_ser = BookModelSerializer(book_list)
            return Response(data=book_list_ser.data)
        # 查所有
        book_list=models.Book.objects.all().filter(is_delete=False)
        book_list_ser=BookModelSerializer(book_list,many=True)
        return Response(data=book_list_ser.data)

 

批量查询关联的处理方式:

#序列化py中的代码
class BookModelSerializer(serializers.ModelSerializer):
    # 一种方案(只序列化可以,反序列化有问题)
    # publish=serializers.CharField(source='publish.name')
    # 第二种方案,models中写方法
    书名 = serializers.CharField(source='name')
    class Meta:
        list_serializer_class = BookListSerializer
        model = models.Book
        # fields = '__all__'
        # 用的少
        # depth=0#直接可以把全部表中的字段拿出来
        fields = ('id','书名','price','authors','publish','publish_name','author_list')
        extra_kwargs = {
            'publish':{'write_only':True},
            'publish_name':{'read_only':True},
            'authors':{'write_only':True},
            'author_list':{'read_only':True}
        }

class Book(BaseModel):
    id = models.AutoField(primary_key=True)
    # verbose_name admin中显示中文
    name = models.CharField(max_length=32, verbose_name='书名', help_text='这里填书名')
    price = models.DecimalField(max_digits=5, decimal_places=2)
    # 一对多的关系一旦确立,关联字段写在多的一方
    # to_field 默认不写,关联到Publish主键
    # db_constraint=False  逻辑上的关联,实质上没有外键练习,增删不会受外键影响,但是orm查询不影响
    publish = models.ForeignKey(to='Publish', on_delete=models.DO_NOTHING, db_constraint=False)

    # 多对多,跟作者,关联字段写在 查询次数多的一方

    # 什么时候用自动,什么时候用手动?第三张表只有关联字段,用自动    第三张表有扩展字段,需要手动写
    # 不能写on_delete
    authors = models.ManyToManyField(to='Author', db_constraint=False)

    class Meta:
        verbose_name_plural = '书表'  # admin中表名的显示
    def __str__(self):
        return self.name
    @property
    def publish_name(self):
        return self.publish.name

    # def author_list(self):
    def author_list(self):
        author_list = self.authors.all()
        # ll=[]
        # for author in author_list:
        #     ll.append({'name':author.name,'sex':author.get_sex_display()})
        # return ll
        return [{'name': author.name, 'sex': author.get_sex_display()} for author in author_list]

批量增加:

    def post(self,request,*args,**kwargs):
        # 具备增单条,和增多条的功能
        if isinstance(request.data,dict):
            book_ser=BookModelSerializer(data=request.data)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(data=book_ser.data)
        elif isinstance(request.data,list):
            #现在book_ser是ListSerializer对象
            from rest_framework.serializers import ListSerializer
            book_ser = BookModelSerializer(data=request.data,many=True)  #增多条
            print('--------',type(book_ser))
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            # 新增---》ListSerializer--》create方法
            # def create(self, validated_data):
            #   self.child是BookModelSerializer对象
            #   print(type(self.child))
            #     return [
            #         self.child.create(attrs) for attrs in validated_data
            #     ]
            return Response(data=book_ser.data)

批量增加内部处理方式

 #内部判断many
 def __new__(cls, *args, **kwargs):
        # We override this method in order to automatically create
        # `ListSerializer` classes instead when `many=True` is set.
        if kwargs.pop('many', False):
            #many为真
            return cls.many_init(*args, **kwargs)
        return super().__new__(cls, *args, **kwargs)

#many为真
        meta = getattr(cls, 'Meta', None)
        list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
        return list_serializer_class(*args, **list_kwargs)    

 批量改:

    def put(self,request,*args,**kwargs):
        # 改一个,改多个
        #改一个个
        if kwargs.get('pk',None):
            book=models.Book.objects.filter(pk=kwargs.get('pk')).first()
            book_ser = BookModelSerializer(instance=book,data=request.data,partial=True)  # 增多条
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(data=book_ser.data)
        else:
            #改多个,
            # 前端传递数据格式[{id:1,name:xx,price:xx},{id:1,name:xx,price:xx}]
            # 处理传入的数据  对象列表[book1,book2]  修改的数据列表[{name:xx,price:xx},{name:xx,price:xx}]
            book_list=[]
            modify_data=[]
       #将前端传过来的list数据遍历 for item in request.data: #{id:1,name:xx,price:xx}           #将遍历出的对象取出id,通过id查询到表中的对象 pk=item.pop('id') book=models.Book.objects.get(pk=pk)
          #查询到的对象存入book_list中 book_list.append(book)
          #遍历后的对象存如modify_date中 modify_data.append(item) # 第一种方案,for循环一个一个修改 #把这个实现 # for i,si_data in enumerate(modify_data):
            #在存放的时候book_list和modify_date是同时存入进去的,在遍历得到的索引就对应着这两个对象 # book_ser = BookModelSerializer(instance=book_list[i], data=si_data) # book_ser.is_valid(raise_exception=True)
           #在保存的时候调用self.child.update保存 # book_ser.save() # return Response(data='成功') # 第二种方案,重写ListSerializer的update方法 book_ser = BookModelSerializer(instance=book_list,data=modify_data,many=True) book_ser.is_valid(raise_exception=True) book_ser.save() #ListSerializer的update方法,自己写的update方法 return Response(book_ser.data) # request.data # book_ser=BookModelSerializer(data=request.data)

单个改在modeserializers在内部就处理好了update,批量改需要自己重写listSerializers的updata方法:

就是将listserializers中的modeserializers遍历出来,调用modserializers的update方法

#写一个类,继ListSerializer,重写update
class BookListSerializer(serializers.ListSerializer):
    # def create(self, validated_data):
    #     print(validated_data)
    #     return super().create(validated_data)
    def update(self, instance, validated_data):
        print(instance)
        print(validated_data)
        # 保存数据
        # self.child:是BookModelSerializer对象
        # ll=[]
        # for i,si_data in enumerate(validated_data):
        #     ret=self.child.update(instance[i],si_data)
        #     ll.append(ret)
        # return ll
        return [
            # self.child.update(对象,字典) for attrs in validated_data
            self.child.update(instance[i],attrs) for i,attrs in enumerate(validated_data)
        ]

批量删除:

    def delete(self,request,*args,**kwargs):
        #单个删除和批量删除
        pk=kwargs.get('pk')
        pks=[]
        if pk:
            # 单条删除
            pks.append(pk)
        #不管单条删除还是多条删除,都用多条删除
        #多条删除
        # {'pks':[1,2,3]}
        else:
            pks=request.data.get('pks')
        #把is_delete设置成true
        # ret返回受影响的行数
        ret=models.Book.objects.filter(pk__in=pks,is_delete=False).update(is_delete=True)
        if ret:
            return Response(data={'msg':'删除成功'})
        else:
            return Response(data={'msg': '没有要删除的数据'})

  

posted @ 2022-03-25 18:08  咖喱给给啊  阅读(65)  评论(0)    收藏  举报