Update nested serializer with an overwritten to_representation

荒凉一梦 提交于 2019-12-11 17:36:08

问题


Context

So i have an AlbumSerializer with a nested TrackSerializer. For convenience on the frontend I overwrite the representation of AlbumSerializer to make a dictionary of the tracks instead of a list.

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ('id', 'order', 'title')
    # directly upsert tracks
    def create(self, validated_data):
            obj, created = Track.objects.update_or_create(
            album_id= validated_data['album_id'],
            order=validated_data['order'],
            defaults={'title': validated_data['title']}
            )
            return obj


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

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

    # make a dictionary of the tracks
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['tracks'] = {track['id']: track for track in representation['tracks']}
        return representation

    #update tracks with the album endpoint
    def update(self, instance, validated_data):
        for track in validated_data['tracks']
            obj, created = Track.objects.update_or_create(
            album_id= track['album_id'],
            order=track['order'],
            defaults={'title': track['title']}
            )
        return instance

Problem

Now when i try to update the album, including some track titles, i receive Expected a list of items but got type \"dict\". Which makes sense.

Question

How can i make DRF accept dictionaries instead of a list if tracks ?

Update: Just learned about drf-rw-serializers. Seems exactly what i need.


回答1:


in update function, you are:

  • trying to loop a dictionary like a list
  • using update_or_create, this will lead to create duplicate tracks

Here is an error fixed code::

def update(self, instance, validated_data):
    for trackid, track in validated_data['tracks'].items():
        obj = Track.objects.filter(id = trackid)
        if obj:
            obj[0].album_id = track['album_id']
            obj[0].order = track['order']
            obj[0].title = title= track['title']
            obj[0].save()
        else:
            Track.objects.create(
                album_id= track['album_id'],
                order=track['order'],  
                title= track['title'])
    return instance


来源:https://stackoverflow.com/questions/56868385/update-nested-serializer-with-an-overwritten-to-representation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!