33

How can I update/append serializer.data in Django Rest Framework?

data = serializer.data.update({"item": "test"}) not working

return Response(serializer.data, status=status.HTTP_201_CREATED)

serializer.data is <class 'rest_framework.utils.serializer_helpers.ReturnDict'>

user4812479812
  • 583
  • 1
  • 6
  • 13

5 Answers5

66

Unfortunately, serializer.data is a property of the class and therefore immutable. Instead of adding items to serializer.data you can copy serializer.data to another dict. You can try this:

newdict={'item':"test"}
newdict.update(serializer.data)
return Response(newdict, status=status.HTTP_201_CREATED)

Read more about property

Mohammed Shareef C
  • 3,829
  • 25
  • 35
  • 3
    i think this is useful for passing additional data in the `Response` that are not part of the serializer/model (thus not validated) – minusf Sep 20 '17 at 09:59
  • this won't solve the case where you want the serialized data to update a model. – adonese Sep 01 '18 at 13:25
  • 2
    What use case would there be for adding updating a model with extra data? In that situation the serializer is probably best to be modified. I can see this solution being useful for maybe adding some computed data or something else unrelated to the resource in a response. – wdfc Sep 28 '18 at 15:53
  • @wdfc I think he may be looking for this: serializer=MySerializer(data=request.data,instance=model_instance,partial=True) serializer.valid() serializer.save() – Mohammed Shareef C Sep 28 '18 at 16:08
  • 1
    In the case you have multiple serialized objects in your serializer.data, you can use something like this: newdict={'item':"test"} newdict.update({'result_from_serializer' :serializer.data}) – Elyas Karimi Jan 29 '23 at 08:28
9

Alternatively you might use SerializerMethodField to add additional data by adding a custom method to the serializer.

http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

You can use such a method to return any data, wether in context of the model or not.

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days
lgespee
  • 131
  • 1
  • 4
  • I had to make just one addition and that was to add 'days_since_joined' to my fields= list. This isn't in the sample code above (or from the DRF documentation), but is required in my implementation. – Animal451 Jul 18 '19 at 06:56
8

You don't.

If you need to pass extra data to the serializer's create/update please do so while calling serializer.save() as explained in the documentation

Linovia
  • 19,812
  • 4
  • 47
  • 48
5

We can update the data passed in response with serializer._data

sample code

class SampleAPIView(generics.CreateAPIView)
    serializer_class = SampleSerializer

    def perform_update(self, serializer):
        application = serializer.save(status='pending')
        my_response_data = {'id': 110, 'name': 'Batta'}
        serializer._data = out_data

serializer._data will make the magic. Reference: https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py#L260

anjaneyulubatta505
  • 10,713
  • 1
  • 52
  • 62
4

The serializer.data object is a instance of ReturnList that is immutable. What you can do to workaround this limitation is transform the serializer.data object into a simple Python list(), then append the value you want so you can use your transformed list in Response() method like this:

def get(self, request):
    serializer = YourAmazingSerializer(many=True)
    new_serializer_data = list(serializer.data)
    new_serializer_data.append({'dict_key': 'dict_value'})
    return Response(new_serializer_data)

Then, your response will have your new obj

Andre Machado
  • 316
  • 2
  • 3