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)