[3.2.x] Fixed #32635 -- Fixed system check crash for reverse o2o relations in CheckConstraint.check and UniqueConstraint.condition.

Regression in b7b7df5fbc.

Thanks Szymon Zmilczak for the report.

Backport of a77c9a4229 from main
This commit is contained in:
Hasan Ramezani 2021-04-13 11:51:19 +02:00 committed by Mariusz Felisiak
parent d6314c4c2e
commit 700356f93b
3 changed files with 49 additions and 0 deletions

View File

@ -2076,6 +2076,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
):

View File

@ -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`).

View File

@ -1694,6 +1694,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):
@ -1933,6 +1954,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()