DRF:views.py中的serializer.save()与serializer.py中的instance.save()有什么区别

Gal*_*row 11 python django django-rest-framework

我对 DRF 序列化器文档感到困惑:

对于序列化器,有人提到,

如果您的对象实例对应于 Django 模型,您还需要确保这些方法将对象保存到数据库中。例如,如果 Comment 是 Django 模型,则方法可能如下所示:

    def create(self, validated_data):
        return Comment.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        instance.save()
        return instance
Run Code Online (Sandbox Code Playgroud)

从serializers.py代码来看,.save()似乎会更新数据库中的实例。

不过后来有人提到,

现在,当反序列化数据时,我们可以根据验证的数据调用 .save() 返回一个对象实例。

comment = serializer.save()

调用 .save() 将创建一个新实例,或更新现有实例,具体取决于实例化序列化器类时是否传递了现有实例:

# .save() will create a new instance.
serializer = CommentSerializer(data=data)

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
Run Code Online (Sandbox Code Playgroud)

似乎在views.py中调用serializer.save()将更新数据库中的“comment”实例。在serializers.py中调用instance.save()也会更新数据库中的“comment”实例。

我的问题是,将实例保存/更新到数据库的两种方法之间是否有区别?

bdb*_*dbd 11

如果你检查serializer.save()正在做什么,它会更有意义(删除了一些行):

    def save(self, **kwargs):
        ... 

        validated_data = dict(
            list(self.validated_data.items()) +
            list(kwargs.items())
        )

        if self.instance is not None:
            self.instance = self.update(self.instance, validated_data)
            assert self.instance is not None, (
                '`update()` did not return an object instance.'
            )
        else:
            self.instance = self.create(validated_data)
            assert self.instance is not None, (
                '`create()` did not return an object instance.'
            )

        return self.instance
Run Code Online (Sandbox Code Playgroud)

因此,每次调用 Serializer's 时save(),您都会获得正在序列化的任何数据的实例。

所以在这种情况下:

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
Run Code Online (Sandbox Code Playgroud)

comment这是一个例子。在序列化程序中传递实例是告诉序列化程序您要更新此实例。所以调用save就会调用self.update

尽管:

# .save() will create a new instance.
serializer = CommentSerializer(data=data)
Run Code Online (Sandbox Code Playgroud)

没有实例(您只有尝试序列化的数据),因此调用save将调用self.create.