From 0bcc92c6917738caa2f08ec16d26fad62974fb47 Mon Sep 17 00:00:00 2001 From: Marc Egli Date: Mon, 14 Apr 2014 14:41:47 -0400 Subject: [PATCH] Fixed #22356 -- Added a check to make sure unique_together fields are local. --- django/db/models/base.py | 13 ++++++++++++ docs/ref/checks.txt | 1 + tests/invalid_models_tests/test_models.py | 24 +++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/django/db/models/base.py b/django/db/models/base.py index 589d793627..b978d9ebdf 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1346,6 +1346,19 @@ class Model(six.with_metaclass(ModelBase)): id='models.E013', ) ) + elif field not in cls._meta.local_fields: + errors.append( + checks.Error( + ("'%s' refers to field '%s' which is not local " + "to model '%s'.") % ( + option, field_name, cls._meta.object_name + ), + hint=("This issue may be caused by multi-table " + "inheritance."), + obj=cls, + id='models.E016', + ) + ) return errors @classmethod diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 98a6e00e73..67dc335d80 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -44,6 +44,7 @@ Models * **models.E013**: ``index_together/unique_together`` refers to a ManyToManyField ````, but ManyToManyFields are not supported for that option. * **models.E014**: ``ordering`` must be a tuple or list (even if you want to order by only one field). * **models.E015**: ``ordering`` refers to the non-existent field ````. +* **models.E016**: ``index_together/unique_together`` refers to field ```` which is not local to model ````. Fields ~~~~~~ diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index e090ade34b..1338fcabcd 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -76,6 +76,30 @@ class IndexTogetherTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) + def test_pointing_to_non_local_field(self): + class Foo(models.Model): + field1 = models.IntegerField() + + class Bar(Foo): + field2 = models.IntegerField() + + class Meta: + index_together = [ + ["field2", "field1"], + ] + + errors = Bar.check() + expected = [ + Error( + ("'index_together' 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', + ), + ] + self.assertEqual(errors, expected) + def test_pointing_to_m2m_field(self): class Model(models.Model): m2m = models.ManyToManyField('self')