mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-14 09:14:47 +03:00
Condition of UniqueTogetherValidator can be read-only (#9764)
* Condition of UniqueValidator can be read-only We can't always expect to find the value of the condition in the serializer if the field is read-only. * Reproducible test
This commit is contained in:
parent
c8b6d3dcdf
commit
513ddb4ffb
|
@ -189,7 +189,12 @@ class UniqueTogetherValidator:
|
||||||
]
|
]
|
||||||
|
|
||||||
condition_sources = (serializer.fields[field_name].source for field_name in self.condition_fields)
|
condition_sources = (serializer.fields[field_name].source for field_name in self.condition_fields)
|
||||||
condition_kwargs = {source: attrs[source] for source in condition_sources}
|
condition_kwargs = {
|
||||||
|
source: attrs[source]
|
||||||
|
if source in attrs
|
||||||
|
else getattr(serializer.instance, source)
|
||||||
|
for source in condition_sources
|
||||||
|
}
|
||||||
if checked_values and None not in checked_values and qs_exists_with_condition(queryset, self.condition, condition_kwargs):
|
if checked_values and None not in checked_values and qs_exists_with_condition(queryset, self.condition, condition_kwargs):
|
||||||
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)
|
||||||
|
|
|
@ -589,6 +589,21 @@ class UniqueConstraintModel(models.Model):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueConstraintReadOnlyFieldModel(models.Model):
|
||||||
|
state = models.CharField(max_length=100, default="new")
|
||||||
|
position = models.IntegerField()
|
||||||
|
something = models.IntegerField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
constraints = [
|
||||||
|
models.UniqueConstraint(
|
||||||
|
name="unique_constraint_%(class)s",
|
||||||
|
fields=("position", "something"),
|
||||||
|
condition=models.Q(state="new"),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class UniqueConstraintNullableModel(models.Model):
|
class UniqueConstraintNullableModel(models.Model):
|
||||||
title = models.CharField(max_length=100)
|
title = models.CharField(max_length=100)
|
||||||
age = models.IntegerField(null=True)
|
age = models.IntegerField(null=True)
|
||||||
|
@ -738,6 +753,31 @@ class TestUniqueConstraintValidation(TestCase):
|
||||||
)
|
)
|
||||||
assert serializer.is_valid()
|
assert serializer.is_valid()
|
||||||
|
|
||||||
|
def test_uniq_constraint_condition_read_only_create(self):
|
||||||
|
class UniqueConstraintReadOnlyFieldModelSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = UniqueConstraintReadOnlyFieldModel
|
||||||
|
read_only_fields = ("state",)
|
||||||
|
fields = ("position", "something", *read_only_fields)
|
||||||
|
serializer = UniqueConstraintReadOnlyFieldModelSerializer(
|
||||||
|
data={"position": 1, "something": 1}
|
||||||
|
)
|
||||||
|
assert serializer.is_valid()
|
||||||
|
|
||||||
|
def test_uniq_constraint_condition_read_only_partial(self):
|
||||||
|
class UniqueConstraintReadOnlyFieldModelSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = UniqueConstraintReadOnlyFieldModel
|
||||||
|
read_only_fields = ("state",)
|
||||||
|
fields = ("position", "something", *read_only_fields)
|
||||||
|
instance = UniqueConstraintReadOnlyFieldModel.objects.create(position=1, something=1)
|
||||||
|
serializer = UniqueConstraintReadOnlyFieldModelSerializer(
|
||||||
|
instance=instance,
|
||||||
|
data={"position": 1, "something": 1},
|
||||||
|
partial=True
|
||||||
|
)
|
||||||
|
assert serializer.is_valid()
|
||||||
|
|
||||||
|
|
||||||
# Tests for `UniqueForDateValidator`
|
# Tests for `UniqueForDateValidator`
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
|
|
Loading…
Reference in New Issue
Block a user