2
votes

I am trying to partially update a record using (partial=True) via my serializer, however, when I look at the sql update statement, it's showing that all fields are being updated when only a subset of fields are being submitted.

class Setting(models.Model):

    comments_enabled = models.BooleanField(default=True)
    visibility = models.CharField(max_length=50, choices=VISIBILITIES,
                              blank=False, null=False,
                              default=VISIBILITY_CHOICE_PARTICIPANTS)
    modified = models.DateTimeField(auto_now=True, blank=True, null=True)

class SettingsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Setting
        fields = ('id', 'comments_enabled', 'visibility', 'modified')


class SomeSerializer(serializers.ModelSerializer):
    def update(self, instance, validated_data):
        settings_serializer = SettingsSerializer(instance.settings, data=validated_data.get('settings'), partial=True)
        settings_serializer.is_valid(raise_exception=True)
        settings_serializer.save() 

I have doubled checked that the validated_data dictionary being passed in only has one field.

I'm using DRF 3.3 and Django 1.9

1
Which fields are updated? Mabe some fields are written in save methodilse2005
Can you post your model?ilse2005
@ilse2005 all fields are being updated. I posted my model as well.dez
Did my answer help you? If so accept it , please.ilse2005

1 Answers

3
votes

I think I got your question now. As stated in the docs you can use the partial keyword to allow partial updates.

By default, serializers must be passed values for all required fields or they will raise validation errors. You can use the partial argument in order to allow partial updates.

This only means that you don't have to post the full object as JSON. As far as I can see the partial argument is only used for validation. In the end the update method of the serializer gets called:

def update(self, instance, validated_data):
    raise_errors_on_nested_writes('update', self, validated_data).
    for attr, value in validated_data.items():
        setattr(instance, attr, value)
    instance.save()

    return instance 

Here the values from validated_data are assigned to the instance. In the end the objects save method is called. And in this method django creates the SQL statement to update all values, because django doesn't know which value changed.