我有一个Django Rest Framework应用程序,其中包含以下(简化)models.py
:
class Photo(models.Model):
...
class Album(models.Model):
...
photos = models.ManyToManyField(Photo, through='PhotoInAlbum', related_name='albums')
class PhotoInAlbum(models.Model):
photo = models.ForeignKey(Photo)
album = models.ForeignKey(Album)
order = models.IntegerField()
class Meta:
ordering = ['album', 'order']
在我的serializers.py
中,我有以下内容:
class AlbumSerializer(serializers.ModelSerializer):
...
photos = serializers.PrimaryKeyRelatedField('photos', many=True)
我的问题是,如何AlbumSerializer
返回字段order
订购的照片?
答案 0 :(得分:5)
看起来处理ManyToManyFields关系的RelatedManager不遵守直通模型的排序。
由于您无法轻松地将序列参数添加到序列化程序字段,因此实现排序的最简单方法是使用序列化程序方法:
class AlbumSerializer(serializers.modelSerializer):
# ...
photos = serializers.SerializerMethodField('get_photos_list')
def get_photos_list(self, instance):
return PhotoInAlbum.objects\
.filter(album_id=instance.id)\
.order_by('order')\
.values_list('photo_id', flat=True)
答案 1 :(得分:5)
自定义查询集的最佳解决方案是使用serializers.SerializerMethodField
,但shezi的回复并不完全正确。您需要从serializer.data
返回SerializerMethodField
。所以解决方案应该是这样的:
class PhotoInAlbumSerializer(serialisers.ModelSerializer):
class Meta:
model = PhotoInAlbum
class AlbumSerializer(serializers.ModelSerializer):
# ...
photos = serializers.SerializerMethodField('get_photos_list')
def get_photos_list(self, instance):
photos = PhotoInAlbum.objects\
.filter(album_id=instance.id)\
.order_by('order')\
.values_list('photo_id', flat=True)
return PhotoInAlbumSerializer(photos, many=True, context=self.context).data
答案 2 :(得分:2)
通常,最简单的方法是在AlbumView
或AlbumViewSet
中执行此操作。
您可以filtering执行此操作 - 在这种情况下,您应该在get_queryset
中定义AlbumViewSet
方法。
无论如何,只要您只获取数据,这是一个很好的解决方案。如果您希望使用POST和PUT方法处理照片,可以通过两种方式完成:
ManyToMany
关系 - 修补create
中的AlbumViewSet
方法以及__create_items
中的restore_object
和AlbumSerializer
方法}} 或
请注意,第二个解决方案不会弄乱AlbumViewSet
(甚至AlbumSerializer
!) - 排序逻辑保留在关系字段代码中。