gpt4 book ai didi

django - 如何展平 django-rest-framework 序列化程序中的对象列表?

转载 作者:行者123 更新时间:2023-12-02 16:58:19 25 4
gpt4 key购买 nike

我有 3 个由 ForeignKey 连接的 django 模型:

# models.py
class Album(models.Model):
some_fields

class Track(models.Model):
some_fields
album = models.ForeignKey(
Album,
related_name='tracks',
on_delete=models.CASCADE,
)

class Comment(models.Model):
some_fields
track = models.ForeignKey(
Track,
related_name='comments',
on_delete=models.CASCADE,
)

我想序列化专辑模型以查看其所有轨道的所有评论。我创建了这样的序列化程序文件:

# serializers.py
class TrackSerializer(serializers.ModelSerializer):

class Meta:
model = Album
fields = (some_fields, 'comments')

class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)

class Meta:
model = Album
fields = (some_fields, 'tracks')

通过这种方式,我获得了所有数据,但在嵌套列表中。我想直接在专辑对象下查看专辑轨道的所有评论。

# Output albums
[{
"some_fields": some_values,
"tracks": [{ "some_fields": some_values, "comments": [ comment1, comment2 ]},
{ "some_fields": some_values, "comments": []},
{ "some_fields": some_values, "comments": [ comment3 ]},]
},
{
"some_fields": some_values,
"tracks": [{ "some_fields": some_values, "comments": [ comment4, comment5 ]},
{ "some_fields": some_values, "comments": []},
{ "some_fields": some_values, "comments": [ comment6 ]},]
}]

# Desired output albums
[{
"some_fields": some_values,
"tracks": [{ "some_fields": some_values},
{ "some_fields": some_values},
{ "some_fields": some_values},],
"comments": [ comment1, comment2, comment3]
},
{
"some_fields": some_values,
"tracks": [{ "some_fields": some_values},
{ "some_fields": some_values},
{ "some_fields": some_values},],
"comments": [ comment4, comment5, comment6]
}]

我试图直接在序列化程序文件中展平列表,但我得到“类型错误:‘ListSerializer’对象不可迭代”。

# serializers.py
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
comments = [comment for track in tracks for comment in track.comments]

class Meta:
model = Album
fields = (some_fields, 'tracks', 'comments')

有没有什么巧妙的方法可以直接用序列化程序输出扁平化的列表?或者我应该稍后在 views.py 中做?现在它看起来像这样:

# views.py
class AlbumMixin(object):
model = Album
raise_exception = True
serializer_class = AlbumSerializer

def get_queryset(self):
return Album.objects.all()

class AlbumList(AlbumMixin, generics.ListCreateAPIView):
pass

最佳答案

您可以在 AlbumSerializer 上添加一个 serializers.SerializerMethodField 并返回必要的注释。

像这样:

class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"


class AlbumSerializer(serializers.ModelSerializer):
comments = serializers.SerializerMethodField()
tracks = TrackSerializer(many=True, read_only=True)

class Meta:
model = Album
fields = (some_fields, "comments", "tracks")

def get_comments(self, obj):
comments = Comment.objects.filter(track__in=obj.tracks.all())
return CommentSerializer(comments, many=True).data
# or you can get rid of CommentSerializer
# return comments.values("some_field")

参见 SerializerMethodField 文档 here

更新

您可以使用@c6754 中的查询来改进查询

comments = Comment.objects.filter(track__album_id=obj.id)

关于django - 如何展平 django-rest-framework 序列化程序中的对象列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55360080/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com