Django Rest Framework的批量,部分更新 [英] Bulk, partial updates with Django Rest Framework

查看:602
本文介绍了Django Rest Framework的批量,部分更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一次部分更新多个项目。我已经添加了一个mixin以允许我批量创建(并且效果很好),但是即使我添加了部分参数,也不允许修补列表。

I want to partially-update multiple items at once. I've already added a mixin for allowing me to bulk-create (and that works well) but even though I've added a partial argument, it doesn't allow for patching a list.

我猜这是一个路由问题。我需要一个新的视图来处理 / 上的PATCH(而不是 / id / ),但我很满意

I'm guessing that this is a routing issue. I need a new view to handle PATCH on / (rather than /id/), but I'm well out of my depth.

现有的答案在3.8版本中无效,或者至少没有对我有效。我需要对以下内容做什么?

Existing answers for this don't work for 3.8, or at least haven't worked for me. What do I need to do to the following?

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


推荐答案

〜10之后数小时将我的头撞在墙上,我决定正确的方式可以坐到后面,而我会用可行的破解方式来弥补。我添加了以下内容

After ~10 hours banging my head against this wall, I decided that the right way could take a back seat and I'd make do with the hack way that works. I added the following gnarlfest to my viewset.

from rest_framework.decorators import action

@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不在查询集中,则它将通过而不是出错。

If I patch in a list of [{id: 123, otherfield: "abc"}, ...] this will now bulk-partial update. I'm fairly sure this is doing n+1 queries and that it'd be a lot more efficient in raw ORM... but for now, it's infinitely better than n requests. Also, if the ID isn't in the queryset, it will pass over rather than erroring. That works for me, but may not for others.

我会在48小时内悬赏该问题,以吸引一些好的答案。

I'll stick a bounty on this question in 48h to tempt in some good answers.

这篇关于Django Rest Framework的批量,部分更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆