mirror of
https://github.com/django/django.git
synced 2025-01-03 06:55:47 +00:00
Refs #30581 -- Made unattached UniqueConstraint(fields) validation testable.
The logic allowing UniqueConstraint(fields).validate to preserve backward compatiblity with Model.unique_error_message failed to account for cases where the constraint might not be attached to a model which is a common pattern during testing. This changes allows for arbitrary UniqueConstraint(fields) to be tested in isolation without requiring actual models backing them up. Co-authored-by: Mark G <mark.gensler@protonmail.com>
This commit is contained in:
parent
5dc17177c3
commit
13922580cc
@ -653,19 +653,16 @@ class UniqueConstraint(BaseConstraint):
|
|||||||
queryset = queryset.exclude(pk=model_class_pk)
|
queryset = queryset.exclude(pk=model_class_pk)
|
||||||
if not self.condition:
|
if not self.condition:
|
||||||
if queryset.exists():
|
if queryset.exists():
|
||||||
if self.expressions:
|
if self.fields:
|
||||||
|
# When fields are defined, use the unique_error_message() for
|
||||||
|
# backward compatibility.
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
self.get_violation_error_message(),
|
instance.unique_error_message(model, self.fields),
|
||||||
code=self.violation_error_code,
|
|
||||||
)
|
)
|
||||||
# When fields are defined, use the unique_error_message() for
|
raise ValidationError(
|
||||||
# backward compatibility.
|
self.get_violation_error_message(),
|
||||||
for model, constraints in instance.get_constraints():
|
code=self.violation_error_code,
|
||||||
for constraint in constraints:
|
)
|
||||||
if constraint is self:
|
|
||||||
raise ValidationError(
|
|
||||||
instance.unique_error_message(model, self.fields),
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
against = instance._get_field_value_map(meta=model._meta, exclude=exclude)
|
against = instance._get_field_value_map(meta=model._meta, exclude=exclude)
|
||||||
try:
|
try:
|
||||||
|
@ -896,6 +896,13 @@ class UniqueConstraintTests(TestCase):
|
|||||||
ChildUniqueConstraintProduct(name=self.p1.name, color=self.p1.color),
|
ChildUniqueConstraintProduct(name=self.p1.name, color=self.p1.color),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_validate_fields_unattached(self):
|
||||||
|
Product.objects.create(price=42)
|
||||||
|
constraint = models.UniqueConstraint(fields=["price"], name="uniq_prices")
|
||||||
|
msg = "Product with this Price already exists."
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
|
constraint.validate(Product, Product(price=42))
|
||||||
|
|
||||||
@skipUnlessDBFeature("supports_partial_indexes")
|
@skipUnlessDBFeature("supports_partial_indexes")
|
||||||
def test_validate_condition(self):
|
def test_validate_condition(self):
|
||||||
p1 = UniqueConstraintConditionProduct.objects.create(name="p1")
|
p1 = UniqueConstraintConditionProduct.objects.create(name="p1")
|
||||||
@ -921,7 +928,7 @@ class UniqueConstraintTests(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@skipUnlessDBFeature("supports_partial_indexes")
|
@skipUnlessDBFeature("supports_partial_indexes")
|
||||||
def test_validate_conditon_custom_error(self):
|
def test_validate_condition_custom_error(self):
|
||||||
p1 = UniqueConstraintConditionProduct.objects.create(name="p1")
|
p1 = UniqueConstraintConditionProduct.objects.create(name="p1")
|
||||||
constraint = models.UniqueConstraint(
|
constraint = models.UniqueConstraint(
|
||||||
fields=["name"],
|
fields=["name"],
|
||||||
|
Loading…
Reference in New Issue
Block a user