相关文章推荐
帅呆的篮球  ·  子查詢 (SQL Server) - ...·  1 月前    · 
至今单身的小蝌蚪  ·  UPDATE - Azure ...·  1 月前    · 
要出家的钥匙扣  ·  java异常 ...·  1 年前    · 
叛逆的青蛙  ·  bootstrap-select ...·  2 年前    · 
耍酷的大象  ·  用 Numba 加速 Python ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I m confused when making api on django rest framework using serializers, please tell me exact different between save(), create() and update() methods, my code sample is as follow,

View.py

class AddUser(views.APIView):
    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)

serializers.py

class UserForAdminSerializer(serializers.ModelSerializer):
    first_name = serializers.CharField(max_length=30)
    last_name = serializers.CharField(max_length=30)
    name = serializers.CharField(max_length=30)
    password = serializers.CharField(max_length=20, style={'input_type': 'password'})
    class Meta:
        model = User
        fields = ('id', 'url', 'first_name', 'last_name', 'name', 'username', 'email', 'password',
                  'total_exp_year', 'total_exp_month', 'voteup_count', 'is_featured',
                  'is_active', 'headline', 'description', 'profile_picture', )
    def create(self, validated_data):
        password = validated_data.pop('password', None)
        instance = self.Meta.model(**validated_data)
        if password is not None:
            instance.set_password(password)
        instance.save()
        return instance

on the above code in view.py file i m used save() method and serializers.py using save() or update() method so please explain me how it's working and clear my confusion between save() and create()

Usually the best way to get a good understanding of the code is to actually read it, so let's take a look at the source:

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

Okay, so, in this base class methods update and create are left to concrete subclasses to be implemented (as details will vary for serializers such as ListSerializer or ModelSerializer).

However, save is implemented and it basically just checks if object is new or existing (if self.instance is not None) and calls update or create respectively. This code will be called in every other serializer.

Let's take a look at concrete subclass:

def create(self, validated_data):
    ... some stuff happening
        # 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

As you can see both create and update call set_many(instance, attr, value) to set values for object attributes. However, create does one critical call before: ModelClass.objects.create(**validated_data). This actually creates new instance.

I hope this clears it up a bit.

Can you explain what is the difference between self and instance in the update definition? – Little Brain Aug 8, 2019 at 16:40 @LittleBrain and to anyone wondering in the future, self is actually the current instance of the Serializer, as instance is an instance of the Model referenced by the Serializer. So the update() method of the Serializer implements how the Serializer should manipulate the model instance. – SinLey Dec 23, 2020 at 10:00

In Django Rest Framework documentation they explained very clearly when to override save method and when create method.

I am posting their explanation here for your convenience

In some cases the .create() and .update() method names may not be meaningful. For example, in a contact form we may not be creating new instances, but instead sending an email or other message. In these cases you might instead choose to override .save() directly, as being more readable and meaningful.
Example:-

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)
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.