From b32080219ebaacbee73f8abd8a9ddc85387f95ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20B=C3=BCchler?= Date: Wed, 19 Jan 2022 16:27:07 +0100 Subject: [PATCH] [4.0.x] Fixed #33449 -- Fixed makemigrations crash on models without Meta.order_with_respect_to but with _order field. Regression in aa4acc164d1247c0de515c959f7b09648b57dc42. Backport of eeff1787b0aa23016e4844c0f537d5093a95a356 from main --- AUTHORS | 1 + django/db/migrations/state.py | 7 ++----- docs/releases/4.0.2.txt | 4 ++++ tests/migrations/test_state.py | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4462b40354..efe78977a8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -304,6 +304,7 @@ answer newbie questions, and generally made Django that much better: Étienne Beaulé Eugene Lazutkin Evan Grim + Fabian Büchler Fabrice Aneche Farhaan Bukhsh favo@exoweb.net diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index d3e2098a67..dfb51d579c 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -685,11 +685,8 @@ class ModelState: return self.name.lower() def get_field(self, field_name): - field_name = ( - self.options['order_with_respect_to'] - if field_name == '_order' - else field_name - ) + if field_name == '_order': + field_name = self.options.get('order_with_respect_to', field_name) return self.fields[field_name] @classmethod diff --git a/docs/releases/4.0.2.txt b/docs/releases/4.0.2.txt index b191ef10e3..28babda393 100644 --- a/docs/releases/4.0.2.txt +++ b/docs/releases/4.0.2.txt @@ -20,3 +20,7 @@ Bugfixes * Fixed a regression in Django 4.0 that caused an incorrect ``repr`` of ``ResolverMatch`` for class-based views (:ticket:`33426`). + +* Fixed a regression in Django 4.0 that caused a crash of ``makemigrations`` on + models without ``Meta.order_with_respect_to`` but with a field named + ``_order`` (:ticket:`33449`). diff --git a/tests/migrations/test_state.py b/tests/migrations/test_state.py index 8ad0d19500..9536f19e83 100644 --- a/tests/migrations/test_state.py +++ b/tests/migrations/test_state.py @@ -959,6 +959,44 @@ class StateTests(SimpleTestCase): ["id", "author"], ) + def test_modelstate_get_field_order_wrt(self): + new_apps = Apps() + + class Author(models.Model): + name = models.TextField() + + class Meta: + app_label = 'migrations' + apps = new_apps + + class Book(models.Model): + author = models.ForeignKey(Author, models.CASCADE) + + class Meta: + app_label = 'migrations' + apps = new_apps + order_with_respect_to = 'author' + + model_state = ModelState.from_model(Book) + order_wrt_field = model_state.get_field('_order') + self.assertIsInstance(order_wrt_field, models.ForeignKey) + self.assertEqual(order_wrt_field.related_model, 'migrations.author') + + def test_modelstate_get_field_no_order_wrt_order_field(self): + new_apps = Apps() + + class HistoricalRecord(models.Model): + _order = models.PositiveSmallIntegerField() + + class Meta: + app_label = 'migrations' + apps = new_apps + + model_state = ModelState.from_model(HistoricalRecord) + order_field = model_state.get_field('_order') + self.assertIsNone(order_field.related_model) + self.assertIsInstance(order_field, models.PositiveSmallIntegerField) + def test_manager_refer_correct_model_version(self): """ #24147 - Managers refer to the correct version of a