API should 400 on unique violations

This commit is contained in:
shamoon 2023-03-08 14:35:10 -08:00
parent 29251b6e38
commit c4ac35164b
2 changed files with 44 additions and 14 deletions

View File

@ -68,6 +68,25 @@ class MatchingModelSerializer(serializers.ModelSerializer):
slug = SerializerMethodField() slug = SerializerMethodField()
def validate(self, data):
# see https://github.com/encode/django-rest-framework/issues/7173
name = data["name"] if "name" in data else self.instance.name
owner = (
data["owner"]
if "owner" in data
else self.user
if hasattr(self, "user")
else None
)
if ("name" in data or "owner" in data) and self.Meta.model.objects.filter(
name=name,
owner=owner,
).exists():
raise serializers.ValidationError(
{"error": "Object violates owner / name unique constraint"},
)
return data
def validate_match(self, match): def validate_match(self, match):
if ( if (
"matching_algorithm" in self.initial_data "matching_algorithm" in self.initial_data
@ -188,7 +207,6 @@ class OwnedObjectSerializer(serializers.ModelSerializer, SetPermissionsMixin):
self._set_permissions(validated_data["set_permissions"], instance) self._set_permissions(validated_data["set_permissions"], instance)
if "owner" in validated_data and "name" in self.Meta.fields: if "owner" in validated_data and "name" in self.Meta.fields:
name = validated_data["name"] if "name" in validated_data else instance.name name = validated_data["name"] if "name" in validated_data else instance.name
print(name)
not_unique = ( not_unique = (
self.Meta.model.objects.exclude(pk=instance.pk) self.Meta.model.objects.exclude(pk=instance.pk)
.filter(owner=validated_data["owner"], name=name) .filter(owner=validated_data["owner"], name=name)
@ -196,7 +214,7 @@ class OwnedObjectSerializer(serializers.ModelSerializer, SetPermissionsMixin):
) )
if not_unique: if not_unique:
raise serializers.ValidationError( raise serializers.ValidationError(
"Object violates owner / name unique constraint", {"error": "Object violates owner / name unique constraint"},
) )
return super().update(instance, validated_data) return super().update(instance, validated_data)

View File

@ -1850,11 +1850,11 @@ class TestDocumentApi(DirectoriesMixin, APITestCase):
user1 = User.objects.create_user(username="test1") user1 = User.objects.create_user(username="test1")
user2 = User.objects.create_user(username="test2") user2 = User.objects.create_user(username="test2")
self.client.post("/api/tags/", {"name": "tag 1"}, format="json") response = self.client.post("/api/tags/", {"name": "tag 1"}, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
with transaction.atomic(): response = self.client.post("/api/tags/", {"name": "tag 1"}, format="json")
with self.assertRaises(IntegrityError): self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.client.post("/api/tags/", {"name": "tag 1"}, format="json")
self.client.post( self.client.post(
"/api/tags/", "/api/tags/",
@ -1862,14 +1862,26 @@ class TestDocumentApi(DirectoriesMixin, APITestCase):
format="json", format="json",
) )
try: response = self.client.post(
self.client.post( "/api/tags/",
"/api/tags/", {"name": "tag 2", "owner": user1.pk},
{"name": "tag 2", "owner": user2.pk}, format="json",
format="json", )
) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
except IntegrityError as e:
assert False, f"Exception {e}" self.client.post(
"/api/tags/",
{"name": "tag 3", "owner": user1.pk},
format="json",
)
response = self.client.post(
"/api/tags/",
{"name": "tag 3", "owner": user2.pk},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_tag_unique_name_and_owner_enforced_on_update(self): def test_tag_unique_name_and_owner_enforced_on_update(self):
user1 = User.objects.create_user(username="test1") user1 = User.objects.create_user(username="test1")