Django Rest-Framework nested serializer order

后端 未结 4 1838
我寻月下人不归
我寻月下人不归 2021-02-05 01:40

Is there a way to order a nested serializer _set, for example order by pk or time-stamp.

So basically order song_set

相关标签:
4条回答
  • 2021-02-05 01:55

    In your ViewSet, you can specify a queryset with a custom Prefetch object that you can filter and order as you like. Prefetching causes just one additional database query (instead of one per parent object when using SerializerMethodField), giving vastly improved performance.

    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')))
    
    0 讨论(0)
  • 2021-02-05 02:00

    Add ordering meta parameter to your Song model:

    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']
    
    0 讨论(0)
  • 2021-02-05 02:02

    Old thread, but because it's still popping up on Google I want to share my answer as well. Try overwriting the Serializer.to_representation method. Now you can basically do whatever you want, including customising the sorting of your response. In your case:

    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
    
    0 讨论(0)
  • 2021-02-05 02:10

    You can use SerializerMethodField and write custom method for this.

    class AlbumSerializer(HyperlinkedModelSerializer):
        song_set = serializers.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
    
    0 讨论(0)
提交回复
热议问题