我想一次部分更新多个项目。我已经添加了一个mixin来允许我进行批量创建(效果很好),但是即使我添加了部分参数,也不允许修补列表。
我猜这是一个路由问题。我需要一个新的视图来处理/
(而不是/id/
)上的PATCH,但我的想法还远远不够。
与此相关的现有答案在3.8版本中无效,或者至少没有对我有效。我需要对以下内容做什么?
class ResourceSerializer(serializers.ModelSerializer):
class Meta:
model = Resource
fields = ('id', 'name', ...)
read_only_fields = ('id',)
class BulkMixin:
def get_serializer(self, *args, **kwargs):
if isinstance(kwargs.get('data', {}), list):
kwargs['many'] = True
kwargs['partial'] = True
return super().get_serializer(*args, **kwargs)
class ResourceViewSet(BulkMixin, viewsets.ModelViewSet):
serializer_class = ResourceSerializer
答案 0 :(得分:1)
大约10个小时后,我将头撞在墙上,我决定正确的方法可以退居二线,而我会使用可行的破解方法。
em>我在视图集上添加了以下最讨厌的内容。@action(methods=['patch'], detail=False)
def bulk_update(self, request):
data = { # we need to separate out the id from the data
i['id']: {k: v for k, v in i.items() if k != 'id'}
for i in request.data
}
for inst in self.get_queryset().filter(id__in=data.keys()):
serializer = self.get_serializer(inst, data=data[inst.id], partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({})
如果我在[{id: 123, otherfield: "abc"}, ...]
列表中打补丁,则现在将进行批量部分更新。我相当确定这是在执行n + 1个查询,并且在原始ORM中效率会更高……但是目前,它比n个请求更好。同样,如果ID不在查询集中,它将通过而不是出错。这对我有用,但对其他人可能无效。
我会在48小时内悬赏这个问题,以吸引一些好的答案。
答案 1 :(得分:0)
我建议不要尝试自己实施。考虑使用django-rest-framework-bulk。它支持批量,部分更新,并提供序列化程序,视图和路由器,以使安装过程变得非常简单。