diff --git a/AUTHORS b/AUTHORS index 6fd36510c7..9ac0d50bd9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -455,6 +455,7 @@ answer newbie questions, and generally made Django that much better: Jacob Kaplan-Moss Jacob Rief Jacob Walls + JaeHyuck Sa Jakub BagiƄski Jakub Paczkowski Jakub Wilk diff --git a/django/contrib/postgres/constraints.py b/django/contrib/postgres/constraints.py index ea06b10d12..e030c1190b 100644 --- a/django/contrib/postgres/constraints.py +++ b/django/contrib/postgres/constraints.py @@ -206,6 +206,11 @@ class ExclusionConstraint(BaseConstraint): self.get_violation_error_message(), code=self.violation_error_code ) else: + # Ignore constraints with excluded fields in condition. + if exclude and self._expression_refs_exclude( + model, self.condition, exclude + ): + return if (self.condition & Exists(queryset.filter(self.condition))).check( replacement_map, using=using ): diff --git a/tests/postgres_tests/test_constraints.py b/tests/postgres_tests/test_constraints.py index 96b5d39092..f107bffcfe 100644 --- a/tests/postgres_tests/test_constraints.py +++ b/tests/postgres_tests/test_constraints.py @@ -797,6 +797,17 @@ class ExclusionConstraintTests(PostgreSQLTestCase): ), exclude={"datespan", "start", "end", "room"}, ) + # Constraints with excluded fields in condition are ignored. + constraint.validate( + HotelReservation, + HotelReservation( + datespan=(datetimes[1].date(), datetimes[2].date()), + start=datetimes[1], + end=datetimes[2], + room=room102, + ), + exclude={"cancelled"}, + ) def test_range_overlaps_custom(self): class TsTzRange(Func):