web-dev-qa-db-ja.com

Django Rest-Frameworkネストされたシリアライザーの順序

ネストされたシリアライザー__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'
        ]
_
15
laa

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
19
Muhammad Hassan

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')))
2
Endre Both

古いスレッドですが、まだ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
1
SaturnFromTitan