summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2024-07-13 22:18:21 -0400
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-07-17 12:52:17 +0200
commitadc0b6aac3f8a5c96e1ca282bc9f46e28d20281c (patch)
treeb98649b463e59d05793d0b3536564e80c4e0f556 /django
parent13922580cccfb9ab2922ff4943dd39da56dfbd8c (diff)
Fixed #35594 -- Added unique nulls distinct validation for expressions.
Thanks Mark Gensler for the report.
Diffstat (limited to 'django')
-rw-r--r--django/db/models/constraints.py12
1 files changed, 8 insertions, 4 deletions
diff --git a/django/db/models/constraints.py b/django/db/models/constraints.py
index 9bb407274c..0a63e38d83 100644
--- a/django/db/models/constraints.py
+++ b/django/db/models/constraints.py
@@ -8,7 +8,7 @@ from django.db import connections
from django.db.models.constants import LOOKUP_SEP
from django.db.models.expressions import Exists, ExpressionList, F, RawSQL
from django.db.models.indexes import IndexExpression
-from django.db.models.lookups import Exact
+from django.db.models.lookups import Exact, IsNull
from django.db.models.query_utils import Q
from django.db.models.sql.query import Query
from django.db.utils import DEFAULT_DB_ALIAS
@@ -642,12 +642,16 @@ class UniqueConstraint(BaseConstraint):
meta=model._meta, exclude=exclude
).items()
}
- expressions = []
+ filters = []
for expr in self.expressions:
if hasattr(expr, "get_expression_for_validation"):
expr = expr.get_expression_for_validation()
- expressions.append(Exact(expr, expr.replace_expressions(replacements)))
- queryset = queryset.filter(*expressions)
+ rhs = expr.replace_expressions(replacements)
+ condition = Exact(expr, rhs)
+ if self.nulls_distinct is False:
+ condition = Q(condition) | Q(IsNull(expr, True), IsNull(rhs, True))
+ filters.append(condition)
+ queryset = queryset.filter(*filters)
model_class_pk = instance._get_pk_val(model._meta)
if not instance._state.adding and model_class_pk is not None:
queryset = queryset.exclude(pk=model_class_pk)