From 6485a5f450b3dc60e690c31a75e0e9574a896842 Mon Sep 17 00:00:00 2001 From: zeyneloz Date: Tue, 30 Apr 2019 12:00:34 +0200 Subject: [PATCH] Fixed #30409 -- Allowed using foreign key's attnames in unique/index_together and Index's fields. --- AUTHORS | 1 + django/db/models/base.py | 8 +++-- tests/invalid_models_tests/test_models.py | 39 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index a27fb7b6d2d..6983965cd19 100644 --- a/AUTHORS +++ b/AUTHORS @@ -918,6 +918,7 @@ answer newbie questions, and generally made Django that much better: Žan Anderle Zbigniew Siciarz zegor + Zeynel Özdemir Zlatko Mašek diff --git a/django/db/models/base.py b/django/db/models/base.py index 0a1120322e8..eeb5163b962 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1571,9 +1571,11 @@ class Model(metaclass=ModelBase): # In order to avoid hitting the relation tree prematurely, we use our # own fields_map instead of using get_field() - forward_fields_map = { - field.name: field for field in cls._meta._get_fields(reverse=False) - } + forward_fields_map = {} + for field in cls._meta._get_fields(reverse=False): + forward_fields_map[field.name] = field + if hasattr(field, 'attname'): + forward_fields_map[field.attname] = field errors = [] for field_name in fields: diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 6b57dd7d9d1..32617555a2f 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -117,6 +117,19 @@ class IndexTogetherTests(SimpleTestCase): ), ]) + def test_pointing_to_fk(self): + class Foo(models.Model): + pass + + class Bar(models.Model): + foo_1 = models.ForeignKey(Foo, on_delete=models.CASCADE, related_name='bar_1') + foo_2 = models.ForeignKey(Foo, on_delete=models.CASCADE, related_name='bar_2') + + class Meta: + index_together = [['foo_1_id', 'foo_2']] + + self.assertEqual(Bar.check(), []) + # unique_together tests are very similar to index_together tests. @isolate_apps('invalid_models_tests') @@ -204,6 +217,19 @@ class UniqueTogetherTests(SimpleTestCase): ), ]) + def test_pointing_to_fk(self): + class Foo(models.Model): + pass + + class Bar(models.Model): + foo_1 = models.ForeignKey(Foo, on_delete=models.CASCADE, related_name='bar_1') + foo_2 = models.ForeignKey(Foo, on_delete=models.CASCADE, related_name='bar_2') + + class Meta: + unique_together = [['foo_1_id', 'foo_2']] + + self.assertEqual(Bar.check(), []) + @isolate_apps('invalid_models_tests') class IndexesTests(SimpleTestCase): @@ -257,6 +283,19 @@ class IndexesTests(SimpleTestCase): ), ]) + def test_pointing_to_fk(self): + class Foo(models.Model): + pass + + class Bar(models.Model): + foo_1 = models.ForeignKey(Foo, on_delete=models.CASCADE, related_name='bar_1') + foo_2 = models.ForeignKey(Foo, on_delete=models.CASCADE, related_name='bar_2') + + class Meta: + indexes = [models.Index(fields=['foo_1_id', 'foo_2'], name='index_name')] + + self.assertEqual(Bar.check(), []) + @isolate_apps('invalid_models_tests') class FieldNamesTests(SimpleTestCase):