Browse Source

Fixed #36222 -- Fixed ExclusionConstraint validation crash on excluded fields in condition.

Signed-off-by: saJaeHyukc <wogur981208@gmail.com>
saJaeHyukc 2 weeks ago
parent
commit
c1257350ca
3 changed files with 17 additions and 0 deletions
  1. 1 0
      AUTHORS
  2. 5 0
      django/contrib/postgres/constraints.py
  3. 11 0
      tests/postgres_tests/test_constraints.py

+ 1 - 0
AUTHORS

@@ -455,6 +455,7 @@ answer newbie questions, and generally made Django that much better:
     Jacob Kaplan-Moss <jacob@jacobian.org>
     Jacob Rief <jacob.rief@gmail.com>
     Jacob Walls <http://www.jacobtylerwalls.com/>
+    JaeHyuck Sa <wogur981208@gmail.com>
     Jakub Bagiński <https://github.com/Jacob1507>
     Jakub Paczkowski <jakub@paczkowski.eu>
     Jakub Wilk <jwilk@jwilk.net>

+ 5 - 0
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
             ):

+ 11 - 0
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):