Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 object created, in this case by order_by('-timestamp') or order_by('-pk').

Json data

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

Model

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) 

Serializer

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'         ] 
like image 551
laa Avatar asked Jan 14 '18 07:01

laa


2 Answers

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 
like image 83
Muhammad Hassan Avatar answered Sep 21 '22 19:09

Muhammad Hassan


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'] 
like image 42
intramuros Avatar answered Sep 19 '22 19:09

intramuros