Django REST Framework单POST请求提交多条JSON数据报错如何解决?
报错原因
默认DRF的ModelViewSet自带的create方法仅处理单个对象的创建请求,仅接受字典格式的JSON入参,你传入列表格式的批量数据自然会触发类型不匹配报错。
解决方案
方案1:重写视图集的create方法,兼容单个/批量创建请求
直接修改你的viewsets.py中my_viewset类的代码,增加create方法的重写逻辑:
from rest_framework import status from rest_framework.response import Response class my_viewset(viewsets.ModelViewSet): queryset = models.my_model.objects.all() # 注意修正原有笔误:序列化器名要和你定义的my_serializer_name一致 serializer_class = serializers.my_serializer_name http_method_names = ['get', 'post'] def list(self, request): queryset = self.get_queryset() serializer = serializers.my_serializer_name(queryset, many=True) return Response(serializer.data) # 新增重写的create方法 def create(self, request, *args, **kwargs): # 识别批量创建场景 if isinstance(request.data, list): serializer = self.get_serializer(data=request.data, many=True) serializer.is_valid(raise_exception=True) self.perform_create(serializer) return Response(serializer.data, status=status.HTTP_201_CREATED) # 原有单个创建逻辑保留 return super().create(request, *args, **kwargs)
方案2:单独新增批量创建的自定义接口(不影响原有单条POST逻辑)
如果不想修改原有默认单条创建的逻辑,可以单独加一个批量接口:
from rest_framework.decorators import action from rest_framework import status from rest_framework.response import Response class my_viewset(viewsets.ModelViewSet): queryset = models.my_model.objects.all() serializer_class = serializers.my_serializer_name http_method_names = ['get', 'post'] def list(self, request): queryset = self.get_queryset() serializer = serializers.my_serializer_name(queryset, many=True) return Response(serializer.data) # 新增批量创建接口,请求路径为 /name/bulk/ @action(methods=['post'], detail=False, url_path='bulk') def bulk_create(self, request): serializer = self.get_serializer(data=request.data, many=True) serializer.is_valid(raise_exception=True) self.perform_create(serializer) return Response(serializer.data, status=status.HTTP_201_CREATED)
使用这个方案时,批量数据需要POST到/name/bulk/地址,原有单条创建还是POST到/name/地址,互不影响。
附加说明
如果需要自定义批量创建的保存逻辑、提升批量插入性能,可以给序列化器指定自定义的ListSerializer,示例如下:
# Serializers.py中修改 class MyListSerializer(serializers.ListSerializer): def create(self, validated_data): # 自定义批量创建逻辑,用bulk_create减少数据库交互次数 data_list = [my_model(**item) for item in validated_data] return my_model.objects.bulk_create(data_list) class my_serializer_name(serializers.ModelSerializer): class Meta: model = my_model fields = '__all__' # 指定批量场景使用的ListSerializer list_serializer_class = MyListSerializer def validate(self, data): # 原有单条数据校验逻辑保留即可 ......
内容的提问来源于stack exchange,提问作者Mehadi
相关产品推荐
相关产品推荐

