Skip to content Skip to sidebar Skip to footer

Django Rest-framework Nested Serializer Order

Is there a way to order a nested serializer _set, for example order by pk or time-stamp. So basically order song_set shown in the json data below from the most recent to the latest

Solution 1:

You can use SerializerMethodField and write custom method for this.

classAlbumSerializer(HyperlinkedModelSerializer):
    song_set = serializers.SerializerMethodField()
    classMeta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

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

Solution 2:

Add ordering meta parameter to your Song model:

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

    classMeta:
        ordering = ['timestamp', 'pk']

Solution 3:

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')))

Solution 4:

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:

classAlbumSerializer(HyperlinkedModelSerializer):
    song_set = SongListSerializer(many=True, read_only=True)
    classMeta:
        model = Album
        fields = [
            'pk',
            'timestamp',
            'song_set'
        ]

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

Post a Comment for "Django Rest-framework Nested Serializer Order"