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

2024-05-15 17:12:49 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我们有以下模型:

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

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


Tags: name模型idnumbermodelmodelsclassroom
3条回答

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

最简单的方法是使用the depth argument

class ClassroomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Classroom
        depth = 1

然而,这将只包括向前关系的关系,在这种情况下,这并不是你所需要的,因为教师领域是一个反向关系。

如果您有更复杂的需求(例如包括反向关系、嵌套某些字段,但不嵌套其他字段,或者只嵌套特定的字段子集),则可以nest serializers,例如。。。

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参数来指定要用作字段源的属性。我们可以通过在Teacher模型上使用source选项来确保存在teachers属性来删除source参数,即classroom = models.ForeignKey(Classroom, related_name='teachers')

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

这也可以通过使用一个非常方便的名为drf-flex-fields的dandy django包来实现。我们用它,它非常棒。只需安装它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,它将返回一个扩展的响应。 希望有一天这能帮上忙。干杯!

相关问题 更多 >