Skip to content

Serializer UniqueConstraint validation fails incorrectly on create with conditional fields #9707

Description

@nefrob

Issue:

Adding the following test to TestUniqueConstraintValidation demonstrates an issue in the serializer’s unique constraint validation logic:

def test_unique_constraint_create(self):
    class SourceUniqueConstraintSerializer(serializers.ModelSerializer):
        raceName = serializers.CharField(source="race_name")

        class Meta:
            model = UniqueConstraintModel
            fields = ("raceName", "position", "global_id", "fancy_conditions")

    UniqueConstraintModel.objects.exclude(pk=self.instance.pk).delete()
    data = {
        "race_name": "other",
        "position": 1,
        "global_id": 3,
        "fancy_conditions": 1,
    }

    obj = UniqueConstraintModel.objects.create(**data)
    obj.delete()

    serializer = SourceUniqueConstraintSerializer(data=data)
    assert serializer.is_valid() # This unexpectedly fails
  • Creating a UniqueConstraintModel instance directly with UniqueConstraintModel.objects.create() succeeds, indicating no unique constraint violation occurs at the database level.
  • However, validating the same data through the ModelSerializer fails.

Root cause:
The unique validator used by the serializer does not account for the global_id field during validation of fancy_conditions, even though global_id is part of the conditional logic in the unique constraint.

As a result, the validation incorrectly identifies a conflict based only on fancy_conditions, without considering that the global_id in the input data should exempt it from the constraint.

Expected behavior:

Serializer validation should succeed in this case, consistent with the model-level behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions