如何使用 Django 剩余框架包含相关的模型字段?

假设我们有以下模型:

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
},
]
},

这可能吗? 如果可能,怎么可能? 这是个坏主意吗?

103859 次浏览

最简单的方法是使用 深度论证深度论证深度论证

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

注意,我们使用序列化器字段上的源参数来指定要用作字段源的属性。我们可以通过在 Teacher模型上使用 Related _ name 相关的 _ name选项来确保 teachers属性的存在来删除 source参数,即。classroom = models.ForeignKey(Classroom, related_name='teachers')

需要记住的一点是,嵌套序列化器当前不支持写操作。对于可写表示,应该使用常规的平面表示,如 pk 或超链接。

谢谢你@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",)

这也可以通过使用称为 Drf-flex-fields的非常方便的花花公子 django 包来实现。我们使用它,它是非常棒的。您只需安装它 pip install drf-flex-fields,通过您的序列化程序,添加 expandable_fields和宾果(例如下面)。它还允许您使用点符号指定深度嵌套关系。

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 中,它将返回一个扩展响应。 希望有一天这能帮到别人,干杯!

感谢“汤姆克里斯蒂”和“保罗”

我只是想添加一个澄清,下面的代码工作得很好,但是人们必须记住向模型教师添加 Related _ name = “ each _ set”属性。在这种情况下,这里是完整的代码:

Models.py

class Classroom(models.Model):
room_number = [...]


class Teacher(models.Model):
name = [...]
tenure = [...]
classroom = models.ForeignKey(Classroom, related_name='teacher_set')

注意: Related _ name = ‘ education _ set’相关 _ name = ‘教师 _ 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",)