Django Rest:基于多个查询集的序列化程序

时间:2017-06-01 16:46:35

标签: django-rest-framework

我正在使用链接描述的序列化工具:Serializer relations (section PrimaryKeyRelatedField)

我有一点点不同的需求,我相信它真的很容易。

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')
    order = models.IntegerField()
    title = models.CharField(max_length=100)
    duration = models.IntegerField()

class SomeWidget(models.Model):
    album = models.ForeignKey(Album)
    track = models.ForeignKey(Track)
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=100)

我的需要,我需要返回以下内容:

{
    'album_name': 'Things We Lost In The Fire',
    'artist': 'Low',
    'tracks': [
        '1: Sunflower',
        '2: Whitetail',
        '3: Dinosaur Act',
        ...
    ],
    'widget': [
        {
           'id': '1234',
           'name': 'my widget',
           'description': 'my description'
        }
    ]
}

我在尝试:

class WidgetField(serializers.RelatedField):
    def to_representation(self, value):
        return {
            'id': '1234'
            ....
        }


class TrackListingField(serializers.RelatedField):
    def to_representation(self, value):
        ...

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackListingField(many=True)
    widget = WidgetField()

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

我一直收到错误:

AssertionError: Relational field must provide a `queryset` argument, override `get_queryset`, or set read_only=`True`.

由于

1 个答案:

答案 0 :(得分:0)

好的,明白了。它花了一点谷歌搜索/试错。显然,您可以覆盖返回字段数据的函数。

例如:

class AlbumSerializer(serializers.ModelSerializer):
    widget = serializers.SerializerMethodField()

    def get_widget(self, data):
        return {
            'id': data.id
        }

或者,您可以执行以下操作:

class WidgetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Widget
        fields = ('id', 'name', 'description',)

....和AlbumSerializer.get_widget函数:

    def get_widget(self, data):
        widget = Widget.objects.get(album=data.album, track=data.track)
        return WidgetSerializer(widget, many=False, context=self.context).data

最后,你没有拥有来使用函数名“get_widget”。您可以随意命名。例如:

class AlbumSerializer(serializers.ModelSerializer):
    widget = serializers.SerializerMethodField("fn_override")

    def fn_override(self, data):
        ....

您可以按照此SO问题中的模式进行操作:Django REST Framework: adding additional field to ModelSerializer