swami
swami

Reputation: 467

How to update multiple objects in django rest framework?

I am trying to update multiple objects using IDs which i am passing in every objects that need to be updated but can't find any way to do it successfully. Here is my code

models.py

class EventTicket(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid_generate_v1mc, editable=False)
    name = models.CharField(max_length=250)
    description = models.TextField(max_length=1000)

views.py

  class EventTicketView(APIView, PaginationHandlerMixin):
        permission_classes = (AllowAny,)
        def get_object(self, ticket_id):
            try:
                return EventTicket.objects.get(id=ticket_id)
            except EventTicket.DoesNotExist():
                raise status.HTTP_400_BAD_REQUEST
        def patch(self, request, *args, **kwargs):
            for each_ticket in request.data:

                ticket_id = self.get_object(each_ticket['ticket_id'])

                serializer = EventTicketSerializer(instance=ticket_id,data=request.data,partial=True)
                if serializer.is_valid():
                    serializer.save()
                    result = {
                        'message': "updated sucessfully"
                    }
                    return Response(result, status=status.HTTP_201_CREATED)
                else:
                    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py

class EventTicketSerializer(serializers.ModelSerializer):
    class Meta:
        model = EventTicket
        fields = ['name', 'description']
```

I have to send data like list of multiple objects :::
[
    {
    "ticket_id": "054665ea-4fde-11ea-94b2-9f415c43ba4c",    
    "name": "chris",
    "description":"The golden ticket for day only",

    },
    {   
    "ticket_id": "054656ea-4fde-11ea-94b2-9f415c43ba4c",
    "name": "daut",
    "description":"The premium ticket for day only",

    }
]

Upvotes: 6

Views: 17311

Answers (1)

Akash Pagar
Akash Pagar

Reputation: 637

The following code will give you a proper understanding of updating multiple objects in single request. For updating multiple objects in a single request it is best practice to use the PUT method instead of PATCH. Here, the body data given is:

{
    "ids":[
        "5e41770d2e8fa013d1f034ec",
        "5e41772c2e8fa013d1f034ee",
        "5e4177702e8fa013d1f034f2",
        "5e453f302e8fa075aa18b277",
        "5e4a314f2e8fa070c5251a0a"
    ]
}

I'm updating the enabled attribute from False to True for given ids of DemoConfig model. In the same way, you can update your data. As per your requirement, you can write validate methods to validate the body data. Serializer is written to serialize the instance data for the response.

class DemoAPI(APIView):

    def get_object(self, obj_id):
        try:
            return DemoConfig.objects.get(id=obj_id)
        except (DemoConfig.DoesNotExist, ValidationError):
            raise status.HTTP_400_BAD_REQUEST
    
    def validate_ids(self, id_list):
        for id in id_list:
            try:
                DemoConfig.objects.get(id=id)
            except (DemoConfig.DoesNotExist, ValidationError):
                raise status.HTTP_400_BAD_REQUEST
        return True

    def put(self, request, *args, **kwargs):
        id_list = request.data['ids']
        self.validate_ids(id_list=id_list)
        instances = []
        for id in id_list:
            obj = self.get_object(obj_id=id)
            obj.enabled = True
            obj.save()
            instances.append(obj)
        serializer = DemoSerializer(instances, many=True)
        return Response(serializer.data)

Serialiser for this view is:

class DemoSerializer(DocumentSerializer):
    class Meta:
        model = DemoConfig
        fields = '__all__'

Output:

{
  "data": [
    {
      "id": "5e41770d2e8fa013d1f034ec",
      "name": "CONFIG_1",
      "enabled": true,
      
    },
    {
      "id": "5e41772c2e8fa013d1f034ee",
      "name": "CONFIG_2",
      "enabled": true,
      
    },
    {
      "id": "5e4177702e8fa013d1f034f2",
      "name": "CONFIG_3",
      "enabled": true,
      
    },
    {
      "id": "5e453f302e8fa075aa18b277",
      "name": "CONFIG_4",
      "enabled": true,
      
    },
    {
      "id": "5e4a314f2e8fa070c5251a0a",
      "name": "CONFIG_5",
      "enabled": true,
      
    }
  ]
}

As per your code requirement, you need to use PUT method in the following way.

    def put(self, request, *args, **kwargs):
        data = request.data
        ticket_ids = [i['ticket_id'] for i in data]
        self.validate_ids(ticket_ids)
        instances = []
        for temp_dict in data:
            ticket_id = temp_dict['ticket_id']
            name = temp_dict['name']
            description = temp_dict['description']
            obj = self.get_object(ticket_id)
            obj.name = name
            obj.description = description
            obj.save()
            instances.append(obj)
        serializer = DemoSerializer(instances, many=True)
        return Response(serializer.data)

Upvotes: 13

Related Questions