Django Rest-Framework嵌套序列化器命令

时间:2018-01-14 07:23:49

标签: python json django rest django-rest-framework

有没有办法订购嵌套序列化程序_set,例如按pktime-stamp订购。

所以基本上在下面的json数据中显示的顺序为song_set,与最新创建的对象最相似,在本例中为order_by('-timestamp')order_by('-pk')

Json数据

{
    "pk": 151,
    "album_name": "Name",
    "song_set": [
         {
           pk: 3,
           timestamp: '5 seconds'
         },
         {
           pk: 2,
           timestamp: '10 seconds'
         },
         {
           pk: 1,
           timestamp: '15 seconds'
         }
    ]
}

模型

class Album(models.Model):
    album_name     = models.CharField(max_length=100, blank=True)


class Song(models.Model):
    album          = models.ForeignKey('album.Album', default=1)
    timestamp      = models.DateTimeField(auto_now_add=True, auto_now=False)

Searilizer

class SongListSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Song
        fields = [
            'pk',
            'timestamp'
        ]

class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = SongListSerializer(many=True, read_only=True)
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

4 个答案:

答案 0 :(得分:14)

您可以使用SerializerMethodField并为此编写自定义方法。

class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = serializer.SerializerMethodField()
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

    def get_song_set(self, instance):
        songs = instance.song_set.all().order_by('-timestamp')
        return SongListSerializer(songs, many=True).data

答案 1 :(得分:9)

向歌曲模型添加 ordering 元参数

class Song(models.Model):
    album = models.ForeignKey('album.Album', default=1)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)

    class Meta:
        ordering = ['timestamp', 'pk']

答案 2 :(得分:0)

旧主题,但由于它仍在Google上弹出,因此我也想分享我的答案。尝试覆盖Serializer.to_representation方法。现在,您基本上可以做任何您想做的事情,包括自定义响应的排序。就您而言:

class AlbumSerializer(HyperlinkedModelSerializer):
    song_set = SongListSerializer(many=True, read_only=True)
    class Meta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response["song_set"] = sorted(response["song_set"], key=lambda x: x["timestamp"])
        return response

答案 3 :(得分:0)

ViewSet中,您可以指定带有自定义Prefetch对象的查询集,您可以根据需要对其进行过滤和排序。预取仅引起一个附加的数据库查询(而不是使用SerializerMethodField时每个父对象一个查询),从而大大提高了性能。

from rest_framework import viewsets
from django.db.models import Prefetch

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.prefetch_related(Prefetch('song_set',
        queryset=Song.objects.order_by('-timestamp')))