2017-08-28 61 views
0

Django Rest Framework文檔有一個可寫嵌套序列化器的示例,請參閱http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers用字符串替代字典的可寫嵌套Django串化器

我對有關Track模型除了外鍵字段只有一個字段(title)的情況感興趣。因此,我修改了它改爲:

models.py

class Album(models.Model): 
    album_name = models.CharField(max_length=100) 
    artist = models.CharField(max_length=100) 

class Track(models.Model): 
    album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE) 
    title = models.CharField(max_length=100) 

    class Meta: 
     unique_together = ('album', 'title') 

serializers.py

class TrackSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Track 
     fields = ('title',) 

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

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

    def create(self, 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 

現在運行:

>>> data = { 
    'album_name': 'The Grey Album', 
    'artist': 'Danger Mouse', 
    'tracks': [ 
     {'title': 'Public Service Announcement'}, 
     {'title': 'What More Can I Say'}, 
     {'title': 'Encore'}, 
    ], 
} 
>>> serializer = AlbumSerializer(data=data) 
>>> serializer.is_valid() 
True 
>>> serializer.save() 
<Album: Album object> 

問:

我需要在序列化數據的軌道被構造爲軌道標題字符串列表,而不是類型的字典{'title': title}的列表,像這樣:

>>> data = { 
    'album_name': 'The Grey Album', 
    'artist': 'Danger Mouse', 
    'tracks': [ 
     'Public Service Announcement', 
     'What More Can I Say', 
     'Encore', 
    ], 
} 

我試圖適應AlbumSerializersto_representationto_internal_value方法,但無法使它與串行器可寫的要求一起工作。我錯過了什麼?

回答

1

您可以嘗試serializermethodfield

tracks = serializers.SerializerMethodField() 

def get_tracks(self, obj): 
    return obj.tracks.values_list('title', flat=True) 

def create(self, validated_data): 
    data = self.context['request'].data.copy() 
    tracks_data = data.get('tracks', []) 
    album = Album.objects.create(**validated_data) 
    for track_data in tracks_data: 
     Track.objects.create(album=album, **track_data) 
    return album 
+0

但那是隻讀的,對不對? – peterthomassen

+0

是的你是對的,如果你想寫你可以重寫'create'方法。 –

+0

在'create'方法中,我們只有'validated_data',它不包含只讀字段。你還有其他建議嗎? – peterthomassen