📜  `.create()` 方法默认不支持可写嵌套字段.为序列化程序 `room_api.serializers.roomSerializer` 编写显式的 `.create()` 方法,或在嵌套的序列化程序字段上设置 `read_only=True`. - Python (1)

📅  最后修改于: 2023-12-03 14:38:59.709000             🧑  作者: Mango

显式编写 .create() 方法或设置 read_only=True

在Django Rest Framework中,当我们定义一个Serializer时,我们必须声明一个 .create() 方法来确定怎么样创建和保存一个新对象。默认情况下,在序列化程序中,如果嵌套有可写字段,.create() 方法将不支持它们,即,我们不能使用默认的 .create() 方法来创建和更新嵌套的对象。

为了解决这个问题,我们可以显式地编写 .create() 方法来处理嵌套字段。此方法采用已验证的数据,并通过嵌套的序列化程序字段递归创建和保存相关的对象。

class roomSerializer(serializers.ModelSerializer):
    nested_serializer = nestedSerializer(many=True)

    def create(self, validated_data):
        nested_data = validated_data.pop('nested_serializer')
        room = Room.objects.create(**validated_data)
        for data in nested_data:
            nested_field = NestedModel.objects.create(room=room, **data)
        return room

    class Meta:
        model = Room
        fields = ['name', 'location', 'nested_serializer']

在这个示例中,我们首先导入相关的序列化程序,即 nestedSerializer。然后我们定义一个新的 .create() 方法,删除嵌套序列化程序字段,并使用已验证的数据来创建和保存 Room 对象。最后,我们创建和保存嵌套数据,并将其与主对象 Room 相关联。

另外,我们还可以通过设置嵌套序列化程序字段的 read_only=True 属性来允许其自动关闭。这将使嵌套字段只在反序列化时使用,并在序列化时排除它们。

class nestedSerializer(serializers.ModelSerializer):

    class Meta:
        model = NestedModel
        fields = '__all__'
        read_only_fields = ('room',)

class roomSerializer(serializers.ModelSerializer):
    nested_serializer = nestedSerializer(many=True, read_only=True)

    class Meta:
        model = Room
        fields = ['name', 'location', 'nested_serializer']

在这个示例中,我们定义一个新的 nestedSerializer 序列化程序,并将其字段 room 标记为只读。然后,我们在 roomSerializer 中将嵌套序列化程序字段 nested_serializer 标记为只读,并指定使用这个新的 nestedSerializer。这将在序列化期间自动排除嵌套字段,并允许它们在反序列化时使用。

总的来说,我们可以通过显式编写 .create() 方法或通过在嵌套序列化程序字段上设置 read_only=True 属性来处理嵌套字段的默认不支持问题。这将使我们能够更轻松地创建、更新和序列化嵌套对象,并解决了我们在开发过程中遇到的一个常见问题。