1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

Used _expression_refs_exclude() hook in CheckConstraint/UniqueConstraint.validate().

This commit is contained in:
Mariusz Felisiak 2025-03-09 19:14:51 +01:00 committed by Sarah Boyce
parent f480d5d3ed
commit e44e8327d3

View File

@ -2,7 +2,7 @@ from enum import Enum
from types import NoneType from types import NoneType
from django.core import checks from django.core import checks
from django.core.exceptions import FieldDoesNotExist, FieldError, ValidationError from django.core.exceptions import FieldDoesNotExist, ValidationError
from django.db import connections from django.db import connections
from django.db.models.constants import LOOKUP_SEP from django.db.models.constants import LOOKUP_SEP
from django.db.models.expressions import Exists, ExpressionList, F, RawSQL from django.db.models.expressions import Exists, ExpressionList, F, RawSQL
@ -206,13 +206,13 @@ class CheckConstraint(BaseConstraint):
def validate(self, model, instance, exclude=None, using=DEFAULT_DB_ALIAS): def validate(self, model, instance, exclude=None, using=DEFAULT_DB_ALIAS):
against = instance._get_field_expression_map(meta=model._meta, exclude=exclude) against = instance._get_field_expression_map(meta=model._meta, exclude=exclude)
try: # Ignore constraints with excluded fields in condition.
if not Q(self.condition).check(against, using=using): if exclude and self._expression_refs_exclude(model, self.condition, exclude):
raise ValidationError( return
self.get_violation_error_message(), code=self.violation_error_code if not Q(self.condition).check(against, using=using):
) raise ValidationError(
except FieldError: self.get_violation_error_message(), code=self.violation_error_code
pass )
def __repr__(self): def __repr__(self):
return "<%s: condition=%s name=%s%s%s>" % ( return "<%s: condition=%s name=%s%s%s>" % (
@ -660,16 +660,18 @@ class UniqueConstraint(BaseConstraint):
code=self.violation_error_code, code=self.violation_error_code,
) )
else: else:
# Ignore constraints with excluded fields in condition.
if exclude and self._expression_refs_exclude(
model, self.condition, exclude
):
return
against = instance._get_field_expression_map( against = instance._get_field_expression_map(
meta=model._meta, exclude=exclude meta=model._meta, exclude=exclude
) )
try: if (self.condition & Exists(queryset.filter(self.condition))).check(
if (self.condition & Exists(queryset.filter(self.condition))).check( against, using=using
against, using=using ):
): raise ValidationError(
raise ValidationError( self.get_violation_error_message(),
self.get_violation_error_message(), code=self.violation_error_code,
code=self.violation_error_code, )
)
except FieldError:
pass