[Solved]-Bulk, partial updates with Django Rest Framework

11👍

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({})

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.

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

👤Oli

1👍

I would suggest not trying to implement this yourself. Consider using django-rest-framework-bulk. It supports bulk, partial updates and provides serializers, views, and a router to make things really simple to setup.

Leave a comment