1
0
mirror of https://github.com/django/django.git synced 2025-01-03 15:06:09 +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:
Simon Charette 2024-07-13 22:09:50 -04:00 committed by Sarah Boyce
parent 5dc17177c3
commit 13922580cc
2 changed files with 16 additions and 12 deletions

View File

@ -653,19 +653,16 @@ class UniqueConstraint(BaseConstraint):
queryset = queryset.exclude(pk=model_class_pk)
if not self.condition:
if queryset.exists():
if self.expressions:
if self.fields:
# When fields are defined, use the unique_error_message() for
# backward compatibility.
raise ValidationError(
self.get_violation_error_message(),
code=self.violation_error_code,
instance.unique_error_message(model, self.fields),
)
# When fields are defined, use the unique_error_message() for
# backward compatibility.
for model, constraints in instance.get_constraints():
for constraint in constraints:
if constraint is self:
raise ValidationError(
instance.unique_error_message(model, self.fields),
)
raise ValidationError(
self.get_violation_error_message(),
code=self.violation_error_code,
)
else:
against = instance._get_field_value_map(meta=model._meta, exclude=exclude)
try:

View File

@ -896,6 +896,13 @@ class UniqueConstraintTests(TestCase):
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")
def test_validate_condition(self):
p1 = UniqueConstraintConditionProduct.objects.create(name="p1")
@ -921,7 +928,7 @@ class UniqueConstraintTests(TestCase):
)
@skipUnlessDBFeature("supports_partial_indexes")
def test_validate_conditon_custom_error(self):
def test_validate_condition_custom_error(self):
p1 = UniqueConstraintConditionProduct.objects.create(name="p1")
constraint = models.UniqueConstraint(
fields=["name"],