mirror of
https://github.com/django/django.git
synced 2024-12-27 19:46:22 +00:00
[4.2.x] Fixed #34291 -- Fixed Meta.constraints validation crash on UniqueConstraint with ordered expressions.
Thanks Dan F for the report. Bug in667105877e
. Backport of2b1242abb3
from main
This commit is contained in:
parent
d43fbdf6f1
commit
719a14badc
@ -2,7 +2,7 @@ from enum import Enum
|
|||||||
|
|
||||||
from django.core.exceptions import FieldError, ValidationError
|
from django.core.exceptions import FieldError, ValidationError
|
||||||
from django.db import connections
|
from django.db import connections
|
||||||
from django.db.models.expressions import Exists, ExpressionList, F
|
from django.db.models.expressions import Exists, ExpressionList, F, OrderBy
|
||||||
from django.db.models.indexes import IndexExpression
|
from django.db.models.indexes import IndexExpression
|
||||||
from django.db.models.lookups import Exact
|
from django.db.models.lookups import Exact
|
||||||
from django.db.models.query_utils import Q
|
from django.db.models.query_utils import Q
|
||||||
@ -338,10 +338,12 @@ class UniqueConstraint(BaseConstraint):
|
|||||||
meta=model._meta, exclude=exclude
|
meta=model._meta, exclude=exclude
|
||||||
).items()
|
).items()
|
||||||
}
|
}
|
||||||
expressions = [
|
expressions = []
|
||||||
Exact(expr, expr.replace_expressions(replacements))
|
for expr in self.expressions:
|
||||||
for expr in self.expressions
|
# Ignore ordering.
|
||||||
]
|
if isinstance(expr, OrderBy):
|
||||||
|
expr = expr.expression
|
||||||
|
expressions.append(Exact(expr, expr.replace_expressions(replacements)))
|
||||||
queryset = queryset.filter(*expressions)
|
queryset = queryset.filter(*expressions)
|
||||||
model_class_pk = instance._get_pk_val(model._meta)
|
model_class_pk = instance._get_pk_val(model._meta)
|
||||||
if not instance._state.adding and model_class_pk is not None:
|
if not instance._state.adding and model_class_pk is not None:
|
||||||
|
@ -10,4 +10,5 @@ in 4.1.5.
|
|||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed a bug in Django 4.1 that caused a crash of model validation on
|
||||||
|
``UniqueConstraint`` with ordered expressions (:ticket:`34291`).
|
||||||
|
@ -672,6 +672,29 @@ class UniqueConstraintTests(TestCase):
|
|||||||
exclude={"name"},
|
exclude={"name"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_validate_ordered_expression(self):
|
||||||
|
constraint = models.UniqueConstraint(
|
||||||
|
Lower("name").desc(), name="name_lower_uniq_desc"
|
||||||
|
)
|
||||||
|
msg = "Constraint “name_lower_uniq_desc” is violated."
|
||||||
|
with self.assertRaisesMessage(ValidationError, msg):
|
||||||
|
constraint.validate(
|
||||||
|
UniqueConstraintProduct,
|
||||||
|
UniqueConstraintProduct(name=self.p1.name.upper()),
|
||||||
|
)
|
||||||
|
constraint.validate(
|
||||||
|
UniqueConstraintProduct,
|
||||||
|
UniqueConstraintProduct(name="another-name"),
|
||||||
|
)
|
||||||
|
# Existing instances have their existing row excluded.
|
||||||
|
constraint.validate(UniqueConstraintProduct, self.p1)
|
||||||
|
# Unique field is excluded.
|
||||||
|
constraint.validate(
|
||||||
|
UniqueConstraintProduct,
|
||||||
|
UniqueConstraintProduct(name=self.p1.name.upper()),
|
||||||
|
exclude={"name"},
|
||||||
|
)
|
||||||
|
|
||||||
def test_validate_expression_condition(self):
|
def test_validate_expression_condition(self):
|
||||||
constraint = models.UniqueConstraint(
|
constraint = models.UniqueConstraint(
|
||||||
Lower("name"),
|
Lower("name"),
|
||||||
|
Loading…
Reference in New Issue
Block a user