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