问题
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