From 8c5a4dbe4118e4700ac88915d5e056efc910cada Mon Sep 17 00:00:00 2001 From: OlhaZahoruiko Date: Thu, 5 Feb 2026 14:58:53 +0100 Subject: [PATCH] :bug: [#718] Fix 500 error on duplicate UUID when creating objects --- src/objects/api/serializers.py | 14 +++++++++++-- src/objects/tests/v2/test_validation.py | 28 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/objects/api/serializers.py b/src/objects/api/serializers.py index 297463ab..e6f18a5b 100644 --- a/src/objects/api/serializers.py +++ b/src/objects/api/serializers.py @@ -3,6 +3,7 @@ import structlog from rest_framework import serializers +from rest_framework.validators import UniqueValidator from rest_framework_gis.serializers import GeometryField from objects.core.models import Object, ObjectRecord, ObjectType, Reference @@ -102,7 +103,13 @@ class ObjectSerializer(DynamicFieldsMixin, serializers.HyperlinkedModelSerialize uuid = serializers.UUIDField( source="object.uuid", required=False, - validators=[IsImmutableValidator()], + validators=[ + IsImmutableValidator(), + UniqueValidator( + queryset=Object.objects.all(), + message=_("An object with this UUID already exists."), + ), + ], help_text=_("Unique identifier (UUID4)"), ) type = ObjectTypeField( @@ -128,13 +135,16 @@ class Meta: @transaction.atomic def create(self, validated_data): object_data = validated_data.pop("object", {}) - if object_type := validated_data.pop("_object_type"): + + if object_type := validated_data.pop("_object_type", None): object_data["object_type"] = object_type + object = Object.objects.create(**object_data) validated_data["object"] = object references = validated_data.pop("references", []) record = super().create(validated_data) + Reference.objects.bulk_create( Reference(record=record, **ref_data) for ref_data in references ) diff --git a/src/objects/tests/v2/test_validation.py b/src/objects/tests/v2/test_validation.py index afdaa70f..cfe22645 100644 --- a/src/objects/tests/v2/test_validation.py +++ b/src/objects/tests/v2/test_validation.py @@ -535,3 +535,31 @@ def test_update_geometry_not_allowed(self, m): response.json()["non_field_errors"], ["This object type doesn't support geometry"], ) + + def test_create_object_with_duplicate_uuid_returns_400(self, m): + mock_service_oas_get(m, OBJECT_TYPES_API, "objecttypes") + m.get( + f"{self.object_type.url}/versions/1", + json=mock_objecttype_version(self.object_type.url), + ) + + url = reverse("object-list") + + data = { + "uuid": "11111111-1111-1111-1111-111111111111", + "type": self.object_type.url, + "record": { + "typeVersion": 1, + "data": {"diameter": 30}, + "startAt": "2026-02-05", + }, + } + + response = self.client.post(url, data, **GEO_WRITE_KWARGS) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.post(url, data, **GEO_WRITE_KWARGS) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual( + response.json()["uuid"], ["An object with this UUID already exists."] + )