ネストされたシリアライザー__set
_を注文する方法はありますか、たとえばpk
または_time-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'
]
_
SerializerMethodField
を使用して、このためのカスタムメソッドを記述できます。
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
ViewSet
で、カスタムPrefetch
オブジェクトを使用してクエリセットを指定し、必要に応じてフィルタリングおよび順序付けできます。プリフェッチにより、データベースクエリが1つだけ追加され(SerializerMethodField
を使用する場合は親オブジェクトごとに1つではなく)、パフォーマンスが大幅に向上します。
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')))
古いスレッドですが、まだ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