我正在尝试使用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'])
请指导如何在单个请求或任何其他方法中进行批量更新和创建。
答案 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