Django其余框架中的批量插入和更新

时间:2018-07-26 06:40:07

标签: python ajax django django-rest-framework

我正在尝试使用https://github.com/miki725/django-rest-framework-bulk在单个请求中进行批量插入和批量更新,以下是我的列表Serilizer和modelViewset。

 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):

    class Meta:
        list_serializer_class = BookListSerializer


 class BookCSVViewSet(generics.BulkModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookCSVSerializer

    def get_serializer(self, *args, **kwargs):
        if "data" in kwargs:
            data = kwargs["data"]

            if isinstance(data, list):
                kwargs["many"] = True

        return super(BookCSVViewSet, self).get_serializer(*args, **kwargs)

    @list_route(methods=['PUT'])
    def bulk_update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        # restrict the update to the filtered queryset
        serializer = self.get_serializer(
            self.filter_queryset(self.get_queryset()),
            data=request.data,
            many=True,
            partial=partial,
        )
        validated_data = []
        validation_errors = []
        for item in request.data:
            print self.get_queryset().get(pk=item['id'])
            item_serializer = self.get_serializer(
                self.get_queryset().get(pk=item['id']),
                data=item,
                partial=partial,
            )
            item_serializer.is_valid(raise_exception=True)
            if item_serializer.errors:
                validation_errors.append(item_serializer.errors)
            validated_data.append(item_serializer.validated_data)
        if validation_errors:
            raise ValidationError(validation_errors)
        serializer._validated_data = validated_data
        self.perform_bulk_update(serializer)
        return Response(serializer.data, status=status.HTTP_200_OK)

我正在同一HTTP请求中同时发送现有记录和新记录

[{id:23, name:"bob", book:"hello"},{id:"299, name:"bob", book:"hello"}]

id:23是一个现有记录,id:299是一个新记录,对于旧记录,它看起来不错,但是当新记录存在时,上面的代码在下面的代码行中失败,因为说不存在匹配查询

 self.get_queryset().get(pk=item['id'])

请指导如何在单个请求或任何其他方法中进行批量更新和创建。

1 个答案:

答案 0 :(得分:2)

我认为,您可以尝试使用“过滤器”而不是使用“获取”。如果找到,它可以更新。如果找不到,我们可以创建。 可能是这样的:

    for item in request.data:
        current_item = self.get_queryset().filter(pk=item['id'])
        if current_item:
            item_serializer = self.get_serializer(current_item.first(),
                data=item,
                partial=partial,
            )
        else:
            new_book = Book.objects.create(name=item['name'], book=item['book'])
            item_serializer = self.get_serializer(new_book)
        item_serializer.is_valid(raise_exception=True)
        if item_serializer.errors:
            validation_errors.append(item_serializer.errors)
        validated_data.append(item_serializer.validated_data)

帮助:v