mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-23 10:03:57 +03:00
Fix unique_together validation with source (#9482)
This commit is contained in:
parent
8e304e1adb
commit
518eb22e67
|
@ -159,17 +159,18 @@ class UniqueTogetherValidator:
|
||||||
queryset = self.filter_queryset(attrs, queryset, serializer)
|
queryset = self.filter_queryset(attrs, queryset, serializer)
|
||||||
queryset = self.exclude_current_instance(attrs, queryset, serializer.instance)
|
queryset = self.exclude_current_instance(attrs, queryset, serializer.instance)
|
||||||
|
|
||||||
|
checked_names = [
|
||||||
|
serializer.fields[field_name].source for field_name in self.fields
|
||||||
|
]
|
||||||
# Ignore validation if any field is None
|
# Ignore validation if any field is None
|
||||||
if serializer.instance is None:
|
if serializer.instance is None:
|
||||||
checked_values = [
|
checked_values = [attrs[field_name] for field_name in checked_names]
|
||||||
value for field, value in attrs.items() if field in self.fields
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
# Ignore validation if all field values are unchanged
|
# Ignore validation if all field values are unchanged
|
||||||
checked_values = [
|
checked_values = [
|
||||||
value
|
attrs[field_name]
|
||||||
for field, value in attrs.items()
|
for field_name in checked_names
|
||||||
if field in self.fields and value != getattr(serializer.instance, field)
|
if attrs[field_name] != getattr(serializer.instance, field_name)
|
||||||
]
|
]
|
||||||
|
|
||||||
if checked_values and None not in checked_values and qs_exists(queryset):
|
if checked_values and None not in checked_values and qs_exists(queryset):
|
||||||
|
|
|
@ -469,6 +469,28 @@ class TestUniquenessTogetherValidation(TestCase):
|
||||||
assert serializer.is_valid()
|
assert serializer.is_valid()
|
||||||
assert not mock.called
|
assert not mock.called
|
||||||
|
|
||||||
|
@patch("rest_framework.validators.qs_exists")
|
||||||
|
def test_unique_together_with_source(self, mock_qs_exists):
|
||||||
|
class UniqueTogetherWithSourceSerializer(serializers.ModelSerializer):
|
||||||
|
name = serializers.CharField(source="race_name")
|
||||||
|
pos = serializers.IntegerField(source="position")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = UniquenessTogetherModel
|
||||||
|
fields = ["name", "pos"]
|
||||||
|
|
||||||
|
data = {"name": "Paris Marathon", "pos": 1}
|
||||||
|
instance = UniquenessTogetherModel.objects.create(
|
||||||
|
race_name="Paris Marathon", position=1
|
||||||
|
)
|
||||||
|
serializer = UniqueTogetherWithSourceSerializer(data=data)
|
||||||
|
assert not serializer.is_valid()
|
||||||
|
assert mock_qs_exists.called
|
||||||
|
mock_qs_exists.reset_mock()
|
||||||
|
serializer = UniqueTogetherWithSourceSerializer(data=data, instance=instance)
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert not mock_qs_exists.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