178

假设我们有以下模型:

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

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

4

4 回答 4

275

最简单的方法是使用深度参数

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

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

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

于 2013-01-29T11:27:15.303 回答
48

谢谢@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",)
于 2016-09-21T17:24:51.277 回答
5

这也可以通过使用名为drf-flex-fields的非常方便的 dandy 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 并返回一个扩展的响应。希望有一天这对某人有所帮助。干杯!

于 2019-07-16T12:01:14.993 回答
0

感谢@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",)
于 2022-01-14T07:58:31.507 回答