user2708386
user2708386

Reputation: 145

Django Rest Framework bulk updates inserting instead of updating

I'm trying to build out a bulk update view for a specific model using Django Rest Framework. In the short term, it only needs to update one field (toggling an invite from submitted=False to submitted=True), but I'd like it to be able to provide more functionality in the future. Whenever I test the view, however, a new object is being created instead of the current one being modified.

I feel like this must be a simple mistake on my part, but I can't figure out what's going on. The serializer object appears to be ignoring the value for "id" passed in through JSON, which may be contributing to the issue. Current code is:

class InviteBulkUpdateView(generics.UpdateAPIView):
    def get_queryset(self):
        order = self.kwargs['order']
        invite = get_objects_for_user(self.request.user, 'sourcing.view_invite')
        return invite.filter(order=order)

    serializer_class = InviteInputSerializer

    def put(self, request, *args, **kwargs):
        data = request.DATA
        serializer = InviteInputSerializer(data=data, many=True)

        if serializer.is_valid():
            serializer.save()
            return Response(status=status.HTTP_200_OK)
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)

class InviteInputSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invite
        fields = ('id', 'order', 'team', 'submitted')

Can anybody shed some light onto what I might be doing wrong?

Upvotes: 12

Views: 22768

Answers (3)

Carlton Gibson
Carlton Gibson

Reputation: 7386

You're not passing object instances to your Serializer. (Thus it will create new instances rather than update.) See the docs on dealing with multiple objects in serializers where you'll see your QuerySet passed in.

Upvotes: 8

Salad.Guyo
Salad.Guyo

Reputation: 3425

Django has update method to handle that. You may want to read full info from django documentation.

Here is a sample code where you can use to update given field for multiple records:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.exceptions import APIException

class Room_Update_ViewSet(APIView):
    def put(self, request,*args, **kwargs):
        hotel_id = self.kwargs.get('hotel_id')
        room_ids = self.request.query_params.get('room_ids')
        room_ids = list(map(int, room_ids.split(',')))
        try:
            Room.objects.filter(hotel_id=hotel_id,id__in=room_ids).update(booked_status=False)
            instances = Room.objects.filter(hotel_id=hotel_id,id__in=room_ids)
            serializer = RoomSerializer(instance=instances, many=True)
            return Response(serializer.data,status=status.HTTP_200_OK)
        except Exception as e:
            print("Error udating rooms-->",e)
            raise APIException

Upvotes: -1

miki725
miki725

Reputation: 27871

Just in case somebody is looking for a library to handle this, I wrote a Django-REST-Framework-bulk which allows to do that in a couple of lines (the example only does bulk update but the library also allows bulk create and delete):

from rest_framework_bulk import ListCreateBulkUpdateAPIView

class FooView(ListCreateBulkUpdateAPIView):
    model = FooModel

Upvotes: 11

Related Questions