Skip to content

Update method ignoring partial flag on serializer (updates all fields) #9240

@mlaxm

Description

@mlaxm

Affected Version: 3.14.0

Link to Code: rest_framework/serializers.py#L928

Documentation Link: Partial Updates

Problem:
The update method in Django Rest Framework's serializers appears to ignore the partial flag, resulting in full saves instead of partial updates as expected. This behavior deviates from the documented functionality.

Steps to Reproduce:
Create a serializer with partial=True.
Attempt to update a model instance with only a subset of fields provided.
Observe that all fields in the instance are updated instead of just the provided ones.

Proof of Concept (PoC):

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["bio", "public_username"]

user = User.objects.get(pk=123)

data = {
    "bio": "new bio",
    "public_username": "new public username",
}
serializer = UserSerializer(user, data=data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()

Expected Behavior:
With the partial=True flag set, only fields provided in the serializer's data should be updated in the database, as documented.

Actual Behavior:
Despite setting partial=True, all fields in the instance are updated upon calling serializer.save(), including those not listed in the serializer's fields, such as password and is_superuser.

Proposed Fix:
A potential fix involves modifying the update method to conditionally use update_fields based on the partial flag. Here's a proposed change:

if self.partial:
    instance.save(update_fields=validated_data.keys())
else:
    instance.save()

Additional Notes:
This issue impacts applications relying on partial updates, potentially leading to unintended modifications of instance's attributes, which may lead to unexpected bugs, race conditions etc.

Environment:

Django==4.2.9
djangorestframework==3.14.0
Python: 3.11

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions