如何使用 Django Rest Framework 包含相关模型字段?
- 2025-03-18 08:56:00
- admin 原创
- 60
问题描述:
假设我们有以下模型:
class Classroom(models.Model):
room_number = [...]
class Teacher(models.Model):
name = [...]
tenure = [...]
classroom = models.ForeignKey(Classroom)
假设您没有按照 ManyRelatedPrimaryKeyField 函数获得如下结果:
{
"room_number": "42",
"teachers": [
27,
24,
7
]
},
让它返回包含完整相关模型表示的内容,例如:
{
"room_number": "42",
"teachers": [
{
'id': 27,
'name': 'John',
'tenure': True
},
{
'id': 24,
'name': 'Sally',
'tenure': False
},
]
},
这可能吗?如果可能,怎么做?这是个坏主意吗?
解决方案 1:
最简单的方法是使用深度参数
class ClassroomSerializer(serializers.ModelSerializer):
class Meta:
model = Classroom
depth = 1
但是,这只包括正向关系,在这种情况下这并不是您所需要的,因为教师领域是反向关系。
如果您有更复杂的要求(例如,包括反向关系,嵌套某些字段,但不嵌套其他字段,或者仅嵌套特定的字段子集),您可以嵌套序列化器,例如......
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set')
class Meta:
model = Classroom
请注意,我们在序列化器字段上使用源参数来指定要用作字段源的属性。我们可以删除该参数,而是使用模型上的related_namesource
选项来确保属性存在,即。teachers
`Teacher`classroom = models.ForeignKey(Classroom, related_name='teachers')
需要注意的是,嵌套序列化器目前不支持写入操作。对于可写表示,您应该使用常规平面表示,例如 pk 或超链接。
解决方案 2:
谢谢@TomChristie!!!你帮了我大忙!我想更新一下(因为我犯了一个错误)
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set', many=True)
class Meta:
model = Classroom
field = ("teachers",)
解决方案 3:
这也可以通过使用非常方便的 django 软件包drf-flex-fields来实现。我们使用它,它非常棒。你只需安装它pip install drf-flex-fields
,将它传递给你的序列化程序,添加expandable_fields
和 bingo(下面的示例)。它还允许你使用点符号指定深度嵌套关系。
from rest_flex_fields import FlexFieldsModelSerializer
class ClassroomSerializer(FlexFieldsModelSerializer):
class Meta:
model = Model
fields = ("teacher_set",)
expandable_fields = {"teacher_set": (TeacherSerializer, {"source": "teacher_set"})}
然后你将其添加?expand=teacher_set
到你的 URL 中,它就会返回扩展的响应。希望这有一天能帮到某人。干杯!
解决方案 4:
感谢@TomChristie 和@Paolo
我只想补充一点,下面的代码运行正常,但用户必须记住将related_name="teacher_set"属性添加到模型教师。在这种情况下,以下是完整的代码:
模型.py
class Classroom(models.Model):
room_number = [...]
class Teacher(models.Model):
name = [...]
tenure = [...]
classroom = models.ForeignKey(Classroom, related_name='teacher_set')
注意:related_name='teacher_set'为教室字段。
序列化器.py
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set', many=True)
class Meta:
model = Classroom
field = ("teachers",)
扫码咨询,免费领取项目管理大礼包!