web-dev-qa-db-fra.com

Django Ordre de sérialiseur imbriqué Rest-Framework

Existe-t-il un moyen de commander un sérialiseur imbriqué _set, Par exemple, commander par pk ou time-stamp.

Donc, en gros, commandez song_set Indiqué dans les données json ci-dessous, du plus récent au dernier objet créé, dans ce cas par order_by('-timestamp') ou order_by('-pk').

données Json

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

Modèle

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

Vous pouvez utiliser SerializerMethodField et écrire une méthode personnalisée pour cela.

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

Dans votre ViewSet, vous pouvez spécifier un ensemble de requêtes avec un objet Prefetch personnalisé que vous pouvez filtrer et ordonner à votre guise. La prélecture ne provoque qu'une seule requête de base de données supplémentaire (au lieu d'une par objet parent lors de l'utilisation de SerializerMethodField), ce qui améliore considérablement les performances.

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

Ancien fil, mais parce qu'il apparaît toujours sur Google, je veux également partager ma réponse. Essayez d'écraser le Serializer.to_representation méthode. Maintenant, vous pouvez essentiellement faire ce que vous voulez, y compris personnaliser le tri de votre réponse. Dans ton cas:

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