[Fixed]-Django Rest Framework: Serialize data from nested json fields to plain object


Finally, solution was found in tests of django-rest-framework.

You may easily define nested serializers which will act as a containers and extract data to your plain object. Like so:

    class NestedSerializer1(serializers.Serializer):
        a = serializers.IntegerField()
        b = serializers.IntegerField()

    class NestedSerializer2(serializers.Serializer):
        c = serializers.IntegerField()
        d = serializers.IntegerField()

    class TestSerializer(serializers.Serializer):
        nested1 = NestedSerializer1(source='*')
        nested2 = NestedSerializer2(source='*')

    data = {
        'nested1': {'a': 1, 'b': 2},
        'nested2': {'c': 3, 'd': 4}

     serializer = TestSerializer(data=self.data)
     assert serializer.is_valid()

     assert serializer.validated_data == {
        'a': 1, 
        'b': 2,
        'c': 3, 
        'd': 4


I would suggest you create your own custom serializer to receive the data. You can do this like so:

from rest_framework import serializers

class MySerializer(serializers.Serializer):
    Custom serializer
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField()

    def create(self, validated_data):
        """Create a new object"""
        validated_data['custom_value'] = 0 # you can manipulate and restructure data here if you wish
        return MyModel.objects.create(**validated_data)

You can then manipulate the data as you wish in the create() function. You could also create nested custom serializers to parse this data.



Documentation has a good part of dealing with nesting in serialisation.

Basically, you want to create a separate class that has the nested values as follows:

class UserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    username = serializers.CharField(max_length=100)

class CommentSerializer(serializers.Serializer):
    user = UserSerializer()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

Leave a comment