Django Rest Framework ListSerializer部分更新

时间:2019-12-20 11:42:18

标签: python django django-rest-framework

我正在编写一个序列化器,以提供对Django模型的多个部分更新。我正在遵循DRF api指南中显示的示例实现,下面复制并链接到此处:https://www.django-rest-framework.org/api-guide/serializers/#customizing-multiple-update

以下内容是从django-rest-framework文档中检索的:

serializer.py

class BookListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data):
        # Maps for id->instance and id->data item.
        book_mapping = {book.id: book for book in instance}
        data_mapping = {item['id']: item for item in validated_data}

        # Perform creations and updates.
        ret = []
        for book_id, data in data_mapping.items():
            book = book_mapping.get(book_id, None)
            if book is None:
                ret.append(self.child.create(data))
            else:
                ret.append(self.child.update(book, data))

        # Perform deletions.
        for book_id, book in book_mapping.items():
            if book_id not in data_mapping:
                book.delete()

        return ret

class BookSerializer(serializers.Serializer):
    # 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 = serializers.IntegerField()
    ...

    class Meta:
        list_serializer_class = BookListSerializer

在我的代码中,当在返回的序列化程序上调用.save()时,我的views.py中出现了 NotImplementedError('update()必须实现。')

我的理解是ListsSerializer会覆盖.update(),所以有人可以帮助解释为什么我收到NotImpletmentedError吗?

views.py

elif request.method == 'PATCH':
        data = JSONParser().parse(request)
        books = Book.objects.all()
        # both partial and many set to True
        serializer = BookSerializer(books, data=data, partial=True, many=True)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

1 个答案:

答案 0 :(得分:1)

在@luistm的帮助下,我设法解决了这个问题。继续上面的DRF示例,在bookSerializer类中对update()重写的实现如下。

serializer.py

class BookSerializer(serializers.Serializer):
    # 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 = serializers.IntegerField()
    ...

    class Meta:
        list_serializer_class = BookListSerializer

    def update(self, instance, validated_data):
         """update the page number of the book and save"""
         instance.page = validated_data.get('page', instance.page)
         instance.save()
         return instance