简体   繁体   English

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

[英]Bulk insert and Update in Django rest frame work

I am trying to do bulkinsert and bulk update in single request using https://github.com/miki725/django-rest-framework-bulk , Below is my list serilizer and modelViewset. 我正在尝试使用https://github.com/miki725/django-rest-framework-bulk在单个请求中进行bulkinsert和批量更新,以下是我的列表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)

I am sending both existing record and new record in the same HTTP request, 我要在同一个HTTP请求中同时发送现有记录和新记录,

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

id:23 is an existing record and id:299 is an new record,for old record it looks fine, however when new record is there above code fails at below line of code, by saying matching query does not exist id:23是一个现有记录,id:299是一个新记录,对于旧记录,它看起来不错,但是当有新记录时,上面的代码在下面的代码行中失败,因为说不存在匹配的查询

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

please guide how can approach bulk update and create in single request or any other approach. 请指导如何在单个请求或任何其他方法中进行批量更新和创建。

In my opinion, you can try 'filter' instead of using 'get'. 我认为,您可以尝试使用“过滤器”而不是使用“获取”。 If found, it can update. 如果找到,它可以更新。 If not found, we can create. 如果找不到,我们可以创建。 May be like this: 可能是这样的:

    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)

Hoop this help :v 圈出这个帮助:v

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM