From 62d85a283500e9abb0e1c9ec53c59be468f056a0 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 26 Jun 2020 23:18:59 +0200 Subject: [PATCH] Fixed #31742 -- Fixed makemigrations crash on ForeignKey to an app with mixed case label. Regression in 9e1b6b8a66af4c2197e5b1b41eb9dbb36e4f6502. Thanks Ignacio Santolin for the report. --- django/db/models/fields/related.py | 6 +++++- tests/migrations/test_state.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index c2aea9c730..397146a354 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -582,7 +582,11 @@ class ForeignObject(RelatedField): if self.remote_field.parent_link: kwargs['parent_link'] = self.remote_field.parent_link if isinstance(self.remote_field.model, str): - kwargs['to'] = self.remote_field.model.lower() + if '.' in self.remote_field.model: + app_label, model_name = self.remote_field.model.split('.') + kwargs['to'] = '%s.%s' % (app_label, model_name.lower()) + else: + kwargs['to'] = self.remote_field.model.lower() else: kwargs['to'] = self.remote_field.model._meta.label_lower # If swappable is True, then see if we're actually pointing to the target diff --git a/tests/migrations/test_state.py b/tests/migrations/test_state.py index 40277bf506..5ac9bf858f 100644 --- a/tests/migrations/test_state.py +++ b/tests/migrations/test_state.py @@ -867,6 +867,34 @@ class StateTests(SimpleTestCase): with self.assertRaisesMessage(ValueError, msg): project_state.apps + def test_reference_mixed_case_app_label(self): + new_apps = Apps() + + class Author(models.Model): + class Meta: + app_label = 'MiXedCase_migrations' + apps = new_apps + + class Book(models.Model): + author = models.ForeignKey(Author, models.CASCADE) + + class Meta: + app_label = 'MiXedCase_migrations' + apps = new_apps + + class Magazine(models.Model): + authors = models.ManyToManyField(Author) + + class Meta: + app_label = 'MiXedCase_migrations' + apps = new_apps + + project_state = ProjectState() + project_state.add_model(ModelState.from_model(Author)) + project_state.add_model(ModelState.from_model(Book)) + project_state.add_model(ModelState.from_model(Magazine)) + self.assertEqual(len(project_state.apps.get_models()), 3) + def test_real_apps(self): """ Including real apps can resolve dangling FK errors.