mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 01:26:53 +03:00
Avoid unnecessary unique together checking (#9154)
This commit is contained in:
parent
2797c0f216
commit
41edb3b9dd
|
@ -160,10 +160,19 @@ class UniqueTogetherValidator:
|
||||||
queryset = self.exclude_current_instance(attrs, queryset, serializer.instance)
|
queryset = self.exclude_current_instance(attrs, queryset, serializer.instance)
|
||||||
|
|
||||||
# Ignore validation if any field is None
|
# Ignore validation if any field is None
|
||||||
checked_values = [
|
if serializer.instance is None:
|
||||||
value for field, value in attrs.items() if field in self.fields
|
checked_values = [
|
||||||
]
|
value for field, value in attrs.items() if field in self.fields
|
||||||
if None not in checked_values and qs_exists(queryset):
|
]
|
||||||
|
else:
|
||||||
|
# Ignore validation if all field values are unchanged
|
||||||
|
checked_values = [
|
||||||
|
value
|
||||||
|
for field, value in attrs.items()
|
||||||
|
if field in self.fields and value != getattr(serializer.instance, field)
|
||||||
|
]
|
||||||
|
|
||||||
|
if checked_values and None not in checked_values and qs_exists(queryset):
|
||||||
field_names = ', '.join(self.fields)
|
field_names = ', '.join(self.fields)
|
||||||
message = self.message.format(field_names=field_names)
|
message = self.message.format(field_names=field_names)
|
||||||
raise ValidationError(message, code='unique')
|
raise ValidationError(message, code='unique')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.db import DataError, models
|
from django.db import DataError, models
|
||||||
|
@ -447,6 +447,22 @@ class TestUniquenessTogetherValidation(TestCase):
|
||||||
serializer = NullUniquenessTogetherSerializer(data=data)
|
serializer = NullUniquenessTogetherSerializer(data=data)
|
||||||
assert not serializer.is_valid()
|
assert not serializer.is_valid()
|
||||||
|
|
||||||
|
def test_ignore_validation_for_unchanged_fields(self):
|
||||||
|
"""
|
||||||
|
If all fields in the unique together constraint are unchanged,
|
||||||
|
then the instance should skip uniqueness validation.
|
||||||
|
"""
|
||||||
|
instance = UniquenessTogetherModel.objects.create(
|
||||||
|
race_name="Paris Marathon", position=1
|
||||||
|
)
|
||||||
|
data = {"race_name": "Paris Marathon", "position": 1}
|
||||||
|
serializer = UniquenessTogetherSerializer(data=data, instance=instance)
|
||||||
|
with patch(
|
||||||
|
"rest_framework.validators.qs_exists"
|
||||||
|
) as mock:
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert not mock.called
|
||||||
|
|
||||||
def test_filter_queryset_do_not_skip_existing_attribute(self):
|
def test_filter_queryset_do_not_skip_existing_attribute(self):
|
||||||
"""
|
"""
|
||||||
filter_queryset should add value from existing instance attribute
|
filter_queryset should add value from existing instance attribute
|
||||||
|
|
Loading…
Reference in New Issue
Block a user