django rest框架中save(),create()和update()之间有什么不同?

时间:2017-07-14 10:18:07

标签: django python-3.x django-rest-framework

我在使用序列化程序在django rest框架上制作api时感到困惑,请告诉我save(),create()和update()方法之间的确切区别,我的代码示例如下,

View.py

类AddUser(views.APIView):


PHP 7.2.0-dev (cli) (built: Mar 31 2017 10:47:40) ( NTS DEBUG )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0-dev, Copyright (c) 1998-2017 Zend Technologies

serializers.py

类UserForAdminSerializer(serializers.ModelSerializer):

serializer_class = UserForAdminSerializer

def post(self, request, *args, **kwargs):

    serializer = UserForAdminSerializer(data=request.data)

    if serializer.is_valid():

        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

在view.py文件中的上述代码中使用save()方法和serializers.py使用save()或update()方法,所以请解释一下它是如何工作的,并清除我在save()和create()之间的混淆

2 个答案:

答案 0 :(得分:5)

通常,了解代码的最佳方法是实际阅读,所以让我们来看看source

tournamnetpresenter = new TournamentPresenter(this, this, getContext());

好的,所以,在这个基类中,方法class BaseSerializer(Field): ... def update(self, instance, validated_data): raise NotImplementedError('`update()` must be implemented.') def create(self, validated_data): raise NotImplementedError('`create()` must be implemented.') def save(self, **kwargs): ... ... a lot of assertions and safety checks ... ... 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) .... else: self.instance = self.create(validated_data) ... return self.instance update留给了要实现的具体子类(因为序列化程序的细节会有所不同,例如create或{{1} })。

但是,ListSerializer 已实现,它基本上只检查对象是新对象还是现有对象(ModelSerializer)并调用saveif self.instance is not None分别。 代码将在其他所有序列化程序中调用。

让我们来看看具体的子类:

update

您可以看到createdef create(self, validated_data): ... ... some stuff happening ... try: # Here is the important part! Creating new object! instance = ModelClass.objects.create(**validated_data) except TypeError: raise TypeError(msg) # Save many-to-many relationships after the instance is created. if many_to_many: for field_name, value in many_to_many.items(): set_many(instance, field_name, value) return instance def update(self, instance, validated_data): raise_errors_on_nested_writes('update', self, validated_data) info = model_meta.get_field_info(instance) # Simply set each attribute on the instance, and then save it. # Note that unlike `.create()` we don't need to treat many-to-many # relationships as being a special case. During updates we already # have an instance pk for the relationships to be associated with. for attr, value in validated_data.items(): if attr in info.relations and info.relations[attr].to_many: set_many(instance, attr, value) else: setattr(instance, attr, value) instance.save() return instance 调用create来设置对象属性的值。但是,update之前会执行一次关键调用:set_many(instance, attr, value)。这实际上创建了新实例。

我希望这有点清除它。

答案 1 :(得分:1)

在Django Rest Framework documentation中,他们非常清楚地解释了何时覆盖save方法以及何时创建方法。

为了您的方便,我在这里发布他们的解释

在某些情况下,.create()和.update()方法名称可能没有意义。例如,在联系表单中,我们可能不会创建新实例,而是发送电子邮件或其他消息。 在这些情况下,您可能会选择直接覆盖.save(),因为它更具可读性和意义。
实施例: -

class ContactForm(serializers.Serializer):
    email = serializers.EmailField()
    message = serializers.CharField()

    def save(self):
        email = self.validated_data['email']
        message = self.validated_data['message']
        send_email(from=email, message=message)