django restframework 实现单个和群体增删改查

前提概要:

一对多模型:

编写模型类:

class AppleModel(models.Model):
    id=models.AutoField(primary_key=True)
    app_name=models.CharField(max_length=50)
    class Meta:
        db_table='tbl_apple'

    def __str__(self):
        return self.app_name

class PickleModel(models.Model):
    id=models.AutoField(primary_key=True)
    app=models.ForeignKey(to="AppleModel",on_delete=models.CASCADE,related_name="pickle")
    color=models.CharField(max_length=20)
    class Meta:
        db_table='tbl_pickle'

    def __str__(self):
       return self.color

  

注册admin.py

from django.contrib import admin
from platformapp.models import AppleModel,PickleModel
# Register your models here.
admin.site.register([AppleModel,PickleModel])

新增主表Apple

 

 新增从表(外键所在表)Pickle:

 

 

修改PIckle:

 

 所以可以感受下增改删页面实现

接下来就是基于djnago restframe work 实现单个和群体增删改查了,首先实现serializer序列化器编写:

class SerPickle(serializers.ModelSerializer):
    # source 格式Pickle模型外键模型字段名.主表的字段属性
    #app_names=serializers.CharField(source="app.app_name",read_only=True)
    class Meta:
        model=PickleModel
        fields="__all__"



class SerApple(serializers.ModelSerializer):

    class Meta:
        model=AppleModel

        fields="__all__"
        

 

控制台看下序列化器长啥样:

 

 

视图编写:

单个post pickle对象和群体post:

视图post:

    def post(self, request, *args, **kwargs):
        data = request.data
        many=False
        if isinstance(data,list):
          many=True
        ser = SerPickle(data=data, many=many)
        if ser.is_valid():
            ser.save()
            return Response(data=ser.data, status=status.HTTP_200_OK)
        else:
            return Response(data=ser.errors, status=status.HTTP_404_NOT_FOUND)

 

单个创建:

 

 

 

群体post创建:

 

 

先写修改单个和群改的视图函数put方法

    def put(self,request,*args,**kwargs):
        data=request.data

        if kwargs.get("id") and isinstance(data,dict):
            inst=PickleModel.objects.filter(id=kwargs.get("id")).first()
            serializer = SerPickle(instance=inst, data=data, many=False)
            if serializer.is_valid():
                serializer.save()
                datas = serializer.data
            else:
                datas = serializer.errors
            return Response(data=datas, status=200)
        elif isinstance(data,list):
            many=True
            pk_objs=[]
            for item in request.data:
                pk=item.pop("id")
                pk_objs.append(pk)
            objs=PickleModel.objects.filter(id__in=pk_objs)
            serializer = SerPickle(instance=objs, data=data, many=True)
            if serializer.is_valid():
                serializer.save()
                datas = serializer.data
            else:
                datas = serializer.errors
            return Response(data=datas, status=200)

  

 

单个修改:

 

 

 

群体修改:

理论上是这样的:

 

 

然后报错:告诉你什么啊,我靠我的serializer默认支持批量创建,并不支持批量修改,如果你要实现请使用ListSerializer` class and override 重写`.update()` 让你更加明确你的调用更新

NotImplementedError at /pickle/ Serializers with many=True do not support multiple update by default, only multiple create. For updates it is unclear how to deal with insertions and deletions. If you need to support multiple update, use a `ListSerializer` class and override `.update()` so you can specify

既然这样那我们就来重写uppate方法吧:

class SerPickleList(serializers.ListSerializer):
    # create 支持不必要重写
    # self.child就代表该ListSerializer类绑定的ModelSerializer类
    def update(self, instance_queryset, validated_data_list):
        queryset=[]
        for index, validated_data in enumerate(validated_data_list):
            inst=self.child.update(instance_queryset[index], validated_data)
            queryset.append(inst)
        return queryset

class SerPickle(serializers.ModelSerializer):
    class Meta:
        model=PickleModel
        fields="__all__"
        # todo 明确使用列表序列化类是谁
        list_serializer_class = SerPickleList

  

 

再来试下:

 

最后补充由于上面的修改都是基于全部修改,实际开发有部分修改场景patch:

所以实现部分修改需要在SerPickle(partial=True)

 

 在视图CBV类加上patch方法:

    def patch(self,request,*args,**kwargs):
        data=request.data

        if kwargs.get("id") and isinstance(data,dict):
            inst=PickleModel.objects.filter(id=kwargs.get("id")).first()
            serializer = SerPickle(instance=inst, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                datas = serializer.data
            else:
                datas = serializer.errors
            return Response(data=datas, status=200)
        elif isinstance(data,list):
            many=True
            pk_objs=[]
            for item in request.data:
                pk=item.pop("id")
                pk_objs.append(pk)
            objs=PickleModel.objects.filter(id__in=pk_objs)
            serializer = SerPickle(instance=objs, data=data, many=True,partial=True)
            if serializer.is_valid():
                serializer.save()
                datas = serializer.data
            else:
                datas = serializer.errors
            return Response(data=datas, status=200)

  

posted @ 2020-12-03 21:19  不带R的墨菲特  阅读(425)  评论(1编辑  收藏  举报