diff options
author | Hasan Ramezani <hasan.r67@gmail.com> | 2021-01-13 20:44:29 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-01-14 12:27:00 +0100 |
commit | f75037731800b7206759768dcdf2fed9e3e3d4ab (patch) | |
tree | 868f502d1a4e92aa12801fb76e9981e3e2365884 /tests/invalid_models_tests | |
parent | 76ae6ccf859bf677bfcb5b992f4c17f5af80ae9d (diff) | |
download | django-f75037731800b7206759768dcdf2fed9e3e3d4ab.tar.gz |
Fixed #32321 -- Added system checks for invalid model field names in functional indexes.
Diffstat (limited to 'tests/invalid_models_tests')
-rw-r--r-- | tests/invalid_models_tests/test_models.py | 95 |
1 files changed, 94 insertions, 1 deletions
diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 3203c26a2e..b20eef7159 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -3,7 +3,7 @@ import unittest from django.core.checks import Error, Warning from django.core.checks.model_checks import _check_lazy_references from django.db import connection, connections, models -from django.db.models.functions import Lower +from django.db.models.functions import Abs, Lower, Round from django.db.models.signals import post_init from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.test.utils import isolate_apps, override_settings, register_lookup @@ -525,6 +525,99 @@ class IndexesTests(TestCase): self.assertEqual(Model.check(databases=self.databases), []) + def test_func_index_complex_expression_custom_lookup(self): + class Model(models.Model): + height = models.IntegerField() + weight = models.IntegerField() + + class Meta: + indexes = [ + models.Index( + models.F('height') / (models.F('weight__abs') + models.Value(5)), + name='name', + ), + ] + + with register_lookup(models.IntegerField, Abs): + self.assertEqual(Model.check(), []) + + def test_func_index_pointing_to_missing_field(self): + class Model(models.Model): + class Meta: + indexes = [models.Index(Lower('missing_field').desc(), name='name')] + + self.assertEqual(Model.check(), [ + Error( + "'indexes' refers to the nonexistent field 'missing_field'.", + obj=Model, + id='models.E012', + ), + ]) + + def test_func_index_pointing_to_missing_field_nested(self): + class Model(models.Model): + class Meta: + indexes = [ + models.Index(Abs(Round('missing_field')), name='name'), + ] + + self.assertEqual(Model.check(), [ + Error( + "'indexes' refers to the nonexistent field 'missing_field'.", + obj=Model, + id='models.E012', + ), + ]) + + def test_func_index_pointing_to_m2m_field(self): + class Model(models.Model): + m2m = models.ManyToManyField('self') + + class Meta: + indexes = [models.Index(Lower('m2m'), name='name')] + + self.assertEqual(Model.check(), [ + Error( + "'indexes' refers to a ManyToManyField 'm2m', but " + "ManyToManyFields are not permitted in 'indexes'.", + obj=Model, + id='models.E013', + ), + ]) + + def test_func_index_pointing_to_non_local_field(self): + class Foo(models.Model): + field1 = models.CharField(max_length=15) + + class Bar(Foo): + class Meta: + indexes = [models.Index(Lower('field1'), name='name')] + + self.assertEqual(Bar.check(), [ + Error( + "'indexes' refers to field 'field1' which is not local to " + "model 'Bar'.", + hint='This issue may be caused by multi-table inheritance.', + obj=Bar, + id='models.E016', + ), + ]) + + def test_func_index_pointing_to_fk(self): + class Foo(models.Model): + pass + + class Bar(models.Model): + foo_1 = models.ForeignKey(Foo, models.CASCADE, related_name='bar_1') + foo_2 = models.ForeignKey(Foo, models.CASCADE, related_name='bar_2') + + class Meta: + indexes = [ + models.Index(Lower('foo_1_id'), Lower('foo_2'), name='index_name'), + ] + + self.assertEqual(Bar.check(), []) + @isolate_apps('invalid_models_tests') class FieldNamesTests(TestCase): |