palazzo train
palazzo train

Reputation: 3409

Django Rest Framework Serializer popped off the validated_data after is_valid() call, causing KeyError in create

I am just following the document to test to write a nested serializer from here

http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

Below is my testing code

    print(data_to_save)
    my_as = AlbumSerializer(data=data_to_save)
    my_as.is_valid()
    print(my_as.validated_data)
    my_as.save()

data_to_save is this

{'album_name': 'Peter ABC', 'artist': 'Peter', 'tracks': [OrderedDict([('order', 1), ('title', 'song 1'), ('duration', 11)]), 

OrderedDict([('order', 2), ('title', 'song 2'), ('duration', 11)])]}

It has a key 'tracks'

After calling is_valid(), the printed validated_data becomes

OrderedDict([('album_name', 'Peter ABC'), ('artist', 'Peter')])

Key 'tracks' kind of popped.

It causes save() error

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

    def create(self, validated_data):
        print(validated_data)

        tracks_data = validated_data.pop('tracks')
        album = Album.objects.create(**validated_data)
        for track_data in tracks_data:
            Track.objects.create(album=album, **track_data)
        return album

tracks_data = validated_data.pop('tracks') will fail. The print(validated_data) inside create() also has 'tracks' key suddenly disappear

{'album_name': 'Peter ABC', 'artist': 'Peter'}

May I know why? My Django version 1.11.4 final and Django Rest Framework version is 3.6.3

Upvotes: 1

Views: 1550

Answers (1)

Ykh
Ykh

Reputation: 7717

tracks = TrackSerializer(many=True)

remove read_only=True in AlbumSerializer

Upvotes: 1

Related Questions