mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-21 17:16:47 +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)
|
||||
|
||||
# Ignore validation if any field is None
|
||||
checked_values = [
|
||||
value for field, value in attrs.items() if field in self.fields
|
||||
]
|
||||
if None not in checked_values and qs_exists(queryset):
|
||||
if serializer.instance is None:
|
||||
checked_values = [
|
||||
value for field, value in attrs.items() if field in self.fields
|
||||
]
|
||||
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)
|
||||
message = self.message.format(field_names=field_names)
|
||||
raise ValidationError(message, code='unique')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import datetime
|
||||
from unittest.mock import MagicMock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from django.db import DataError, models
|
||||
|
@ -447,6 +447,22 @@ class TestUniquenessTogetherValidation(TestCase):
|
|||
serializer = NullUniquenessTogetherSerializer(data=data)
|
||||
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):
|
||||
"""
|
||||
filter_queryset should add value from existing instance attribute
|
||||
|
|
Loading…
Reference in New Issue
Block a user