Django.rest_framework:如何序列化一对多?

时间:2014-07-15 14:09:55

标签: python django serialization django-queryset django-rest-framework

我有一些用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三个序列化器中写的:

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,)

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

我应该在School序列化程序中使用哪个源直接返回桌面?像source =' room_set.desk_set'?或者也许通过使用transform_函数?

PS:代码是从头开始写的,请忽略可能的语法错误

1 个答案:

答案 0 :(得分:17)

如果我正确理解你,你希望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)。

希望这有帮助。