【问题标题】:Writable nested Django serializer with string instead of dict带有字符串而不是字典的可写嵌套 Django 序列化程序
【发布时间】:2017-08-28 17:33:24
【问题描述】:

Django Rest Framework 文档有一个可写嵌套序列化器的示例,请参阅http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

我感兴趣的是相关的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 方法,但无法使其满足序列化程序可写的要求。我错过了什么?

【问题讨论】:

    标签: python django serialization nested


    【解决方案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
    

    【讨论】:

    • 是的,你是对的,如果你想写你可以覆盖create方法。
    • create 方法中,我们只有validated_data,它不包含只读字段。您还有其他想法吗?
    • 尝试 data = self.context['request'].data.copy() 在里面创建
    • 谢谢!也许您可以更新您的初始答案以反映可写条件。
    • 很高兴帮到你,加create
    猜你喜欢
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2018-03-02
    • 1970-01-01
    相关资源
    最近更新 更多