rest_框架:如何序列化一对多对多?

2024-04-18 04:24:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我在和django连载时遇到了一些麻烦。 我有三个模型,比如说一个学校,一个房间和一张桌子(比如虚拟名字)。 每个学校有多个房间,每个房间有多张桌子。

类及其关系如下所示:

class School(models.Model):
    name = models.CharField()

class Room(models.Model):
    name = models.CharField()
    school_id = models.ForeignKey(School)

class Desk(models.Model):
    row = models.IntegerField()
    col = models.IntegerField()
    room_id = models.ForeignKey(Room)

我想能够连载一份学校名单,每个名单都直接包含了里面所有的课桌。

我得到的壁橱是在serialize.py three serializer中编写的:

class DeskSerializer(serializers.ModelSerializer):
    class Meta:
        field = (row, col,)

class RoomSerializer(serializers.ModelSerializer):

    desks = DeskSerializer(source='desk_set', many=True)
    class Meta:
        field = (desks,)

class SchoolSerializer(serializers.ModelSerializer):

    rooms = RoomSerializer(source='room_set', many=True)
    class Meta:
        field = (name, rooms,)

当我想要一个包含书桌列表的学校列表时,返回一个包含书桌列表的房间列表的学校列表

我应该在学校序列化程序中使用哪个源直接返回桌面?像source='room_set.desk_set'?或者使用转换函数?

备注:代码是从零开始写的,请忽略可能的语法错误


Tags: namefieldsource列表modelmodelsmeta学校
1条回答
网友
1楼 · 发布于 2024-04-18 04:24:52

如果我理解正确,您希望SchoolSerializer返回2层深的嵌套结构,但跳过中间模型。为此,我将在School模型中创建一个方法来检索Desk实例:

class School(models.Model):
    ...

    def get_desks(self):
        rooms = Room.objects.filter(school=self)
        desks = Desk.objects.filter(room__in=rooms)
        return desks

然后,在SchoolSerializer中包含一个字段,该字段使用该方法并通过DeskSerializer按您的意愿呈现返回的实例:

class SchoolSerializer(serializers.ModelSerializer):
    ...
    desks = DeskSerializer(
        source='get_desks',
        read_only=True
    )

    class Meta:
        field = (name, desks)

理解其工作原理的关键是,用作source参数值的模型方法必须只返回该序列化程序模型的实例。序列化程序从那里获取它,呈现在序列化程序中定义的对象(在本例中是DeskSerializer)。

希望这有帮助。

相关问题 更多 >