Django Rest Framework的批量,部分更新

时间:2018-11-03 09:44:16

标签: django django-rest-framework

我想一次部分更新多个项目。我已经添加了一个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

2 个答案:

答案 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。它支持批量,部分更新,并提供序列化程序,视图和路由器,以使安装过程变得非常简单。