如何在 django Rest 框架中使用 ListSerializer 创建和更新多条记录?

Bha*_*ani 5 python django multiple-instances insert-update django-rest-framework

以下是使用 ListSerializer 在 django Rest 框架中一次创建和更新多个记录的方法。这种方式非常排序并且响应速度快。

当您想要创建对象时,请传递id: null因为id是必填字段,当您想要更新记录时,请传递特定 id。

答案如下:

模型.py

class BookDetail(models.Model):
    author = models.ForeignKey('bookapp.Author', null=True, on_delete=models.CASCADE)
    title = models.CharField(max_length=255, null=True, blank=True)
    price = models.CharField(max_length=100, null=True, blank=True)
    discount = models.FloatField(default=0)
    tax_percentage = models.IntegerField(default=0)
    total_price = models.FloatField(default=0)

    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    modified_at = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)

序列化器.py

class BookDetailsListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data):
        # Perform creations and updates.
        ret = []

        for data in validated_data:
            if "id" in data and data['id'] not in ['', None]:
                BookDetail.objects.filter(id=data['id']).update(**data)
                ret.append(data)
            else:
                ret.append(BookDetail.objects.create(**data))
        return ret

    
class BookDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = BookDetail
        fields = ['id', 'author', 'title', 'price', 'discount', 'tax_percentage', 'total_price']
        list_serializer_class = BookDetailsListSerializer
        extra_kwargs = {
            # We need to identify elements in the list using their primary key,
            # so use a writable field here, rather than the default which would be read-only.
            'id':{
                'read_only': False,
                'allow_null': True,
            },
            'author':{
                'required': True,
            },
            'title':{
                'required': True,
            },
            'price':{
                'required': True,
            },
            'discount':{
                'required': True,
            },
            'tax_percentage':{
                'required': True,
            },
            'total_price':{
                'required': True,
            }
        }
Run Code Online (Sandbox Code Playgroud)

urls.py

path('book-details', views.BookDetailsView.as_view()),
Run Code Online (Sandbox Code Playgroud)

视图.py

class BookDetailsView(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    serializer_class = BookDetailsSerializer

    def get(self, request, *args, **kwargs):
        author_id = request.GET.get('author_id', None)
        bookdtl_obj = BookDetail.objects.filter(author__id=a)
        serializer = self.serializer_class(bookdtl_obj, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)
    
    def post(self, request, *args, **kwargs):
        data = request.data
        serializer = self.serializer_class(instance='',data=data, many=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

在这里,我附上了使用邮递员创建多个书籍对象的屏幕截图:

在此输入图像描述

在这里,我附上了使用邮递员更新多个书籍对象的屏幕截图:

在此输入图像描述