Django.rest_framework:如何序列化一对多?
Posted
技术标签:
【中文标题】Django.rest_framework:如何序列化一对多?【英文标题】:Django.rest_framework: How to serialize one to many to many? 【发布时间】:2014-09-05 18:45:28 【问题描述】:我在使用 django 进行序列化时遇到了一些问题。 我有三个模型,比如说学校、房间和办公桌(例如虚拟名称)。 每个 School 有多个 Room,每个 Room 有多个 Desk。
类及其关系如下所示:
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】:如果我对您的理解正确,您希望 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
)。
希望这会有所帮助。
【讨论】:
你可以在一个查询中做到这一点:desks = Desk.objects.filter(room__school=self)以上是关于Django.rest_framework:如何序列化一对多?的主要内容,如果未能解决你的问题,请参考以下文章
python Django Rest_Framework框架 模型类序列化器(ModelSerializer)详解(图文并茂版)