有没有办法订购嵌套序列化程序_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'
]
答案 0 :(得分:14)
您可以使用SerializerMethodField
并为此编写自定义方法。
class AlbumSerializer(HyperlinkedModelSerializer):
song_set = serializer.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
答案 1 :(得分:9)
向歌曲模型添加 ordering 元参数
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']
答案 2 :(得分:0)
旧主题,但由于它仍在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
答案 3 :(得分:0)
在ViewSet
中,您可以指定带有自定义Prefetch
对象的查询集,您可以根据需要对其进行过滤和排序。预取仅引起一个附加的数据库查询(而不是使用SerializerMethodField
时每个父对象一个查询),从而大大提高了性能。
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')))