summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHasan Ramezani <hasan.r67@gmail.com>2021-04-13 11:51:19 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-04-14 10:06:18 +0200
commita77c9a4229cfef790ec18001b2cd18bd9c4aedbc (patch)
treef45666c69c77f76d01674d00d6b3750b4767fa86
parent33abc55601107e9f12db3f0c16b3498b26c445f2 (diff)
Fixed #32635 -- Fixed system check crash for reverse o2o relations in CheckConstraint.check and UniqueConstraint.condition.
Regression in b7b7df5fbcf44e6598396905136cab5a19e9faff. Thanks Szymon Zmilczak for the report.
-rw-r--r--django/db/models/base.py2
-rw-r--r--docs/releases/3.2.1.txt4
-rw-r--r--tests/invalid_models_tests/test_models.py43
3 files changed, 49 insertions, 0 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 55b1691166..cd5268bed1 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -2105,6 +2105,8 @@ class Model(metaclass=ModelBase):
# JOIN must happen at the first lookup.
first_lookup = lookups[0]
if (
+ hasattr(field, 'get_transform') and
+ hasattr(field, 'get_lookup') and
field.get_transform(first_lookup) is None and
field.get_lookup(first_lookup) is None
):
diff --git a/docs/releases/3.2.1.txt b/docs/releases/3.2.1.txt
index 376efb0211..cc716782e5 100644
--- a/docs/releases/3.2.1.txt
+++ b/docs/releases/3.2.1.txt
@@ -22,3 +22,7 @@ Bugfixes
* Restored, following a regression in Django 3.2, displaying an exception
message on the technical 404 debug page (:ticket:`32637`).
+
+* Fixed a bug in Django 3.2 where a system check would crash on a reverse
+ one-to-one relationships in ``CheckConstraint.check`` or
+ ``UniqueConstraint.condition`` (:ticket:`32635`).
diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py
index 6c3017ff47..958ad120ca 100644
--- a/tests/invalid_models_tests/test_models.py
+++ b/tests/invalid_models_tests/test_models.py
@@ -1695,6 +1695,27 @@ class ConstraintsTests(TestCase):
])
@skipUnlessDBFeature('supports_table_check_constraints')
+ def test_check_constraint_pointing_to_reverse_o2o(self):
+ class Model(models.Model):
+ parent = models.OneToOneField('self', models.CASCADE)
+
+ class Meta:
+ constraints = [
+ models.CheckConstraint(
+ name='name',
+ check=models.Q(model__isnull=True),
+ ),
+ ]
+
+ self.assertEqual(Model.check(databases=self.databases), [
+ Error(
+ "'constraints' refers to the nonexistent field 'model'.",
+ obj=Model,
+ id='models.E012',
+ ),
+ ])
+
+ @skipUnlessDBFeature('supports_table_check_constraints')
def test_check_constraint_pointing_to_m2m_field(self):
class Model(models.Model):
m2m = models.ManyToManyField('self')
@@ -1943,6 +1964,28 @@ class ConstraintsTests(TestCase):
)
] if connection.features.supports_partial_indexes else [])
+ def test_unique_constraint_pointing_to_reverse_o2o(self):
+ class Model(models.Model):
+ parent = models.OneToOneField('self', models.CASCADE)
+
+ class Meta:
+ required_db_features = {'supports_partial_indexes'}
+ constraints = [
+ models.UniqueConstraint(
+ fields=['parent'],
+ name='name',
+ condition=models.Q(model__isnull=True),
+ ),
+ ]
+
+ self.assertEqual(Model.check(databases=self.databases), [
+ Error(
+ "'constraints' refers to the nonexistent field 'model'.",
+ obj=Model,
+ id='models.E012',
+ ),
+ ] if connection.features.supports_partial_indexes else [])
+
def test_deferrable_unique_constraint(self):
class Model(models.Model):
age = models.IntegerField()