summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2022-08-19 14:03:15 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-08-25 10:32:48 +0200
commitc9ebd5b7aa82c2958c59786a9925037602ab00b8 (patch)
tree7e7dbb2fbf579cda299e399d4747bbcaa6b0a1b8
parent2984e17c6453fac63bac2610bad508b2e5bb5324 (diff)
[4.1.x] Fixed #33938 -- Fixed migration crash for m2m with a through model in another app.
Regression in aa4acc164d1247c0de515c959f7b09648b57dc42. Thanks bryangeplant for the report. Backport of 71902e0d9f93670c4f93ff9d66095b0e571be74b from main
-rw-r--r--django/db/migrations/autodetector.py2
-rw-r--r--docs/releases/4.1.1.txt3
-rw-r--r--tests/migrations/test_autodetector.py46
3 files changed, 50 insertions, 1 deletions
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
index 4bcbae8bd3..a904ce0986 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -1418,7 +1418,7 @@ class MigrationAutodetector:
dependencies = [(dep_app_label, dep_object_name, None, True)]
if getattr(field.remote_field, "through", None):
through_app_label, through_object_name = resolve_relation(
- remote_field_model,
+ field.remote_field.through,
app_label,
model_name,
)
diff --git a/docs/releases/4.1.1.txt b/docs/releases/4.1.1.txt
index 39b1306234..2ae2ecfb1d 100644
--- a/docs/releases/4.1.1.txt
+++ b/docs/releases/4.1.1.txt
@@ -43,3 +43,6 @@ Bugfixes
* Fixed a regression in Django 4.1 that caused a migration crash on PostgreSQL
when altering ``AutoField``, ``BigAutoField``, or ``SmallAutoField`` to
``OneToOneField`` (:ticket:`33932`).
+
+* Fixed a migration crash on ``ManyToManyField`` fields with ``through``
+ referencing models in different apps (:ticket:`33938`).
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py
index 33411c9e3e..ad92892160 100644
--- a/tests/migrations/test_autodetector.py
+++ b/tests/migrations/test_autodetector.py
@@ -3700,6 +3700,52 @@ class AutodetectorTests(TestCase):
changes, "testapp", 0, 3, model_name="author", name="publishers"
)
+ def test_create_with_through_model_separate_apps(self):
+ author_with_m2m_through = ModelState(
+ "authors",
+ "Author",
+ [
+ ("id", models.AutoField(primary_key=True)),
+ (
+ "publishers",
+ models.ManyToManyField(
+ "testapp.Publisher", through="contract.Contract"
+ ),
+ ),
+ ],
+ )
+ contract = ModelState(
+ "contract",
+ "Contract",
+ [
+ ("id", models.AutoField(primary_key=True)),
+ ("author", models.ForeignKey("authors.Author", models.CASCADE)),
+ ("publisher", models.ForeignKey("testapp.Publisher", models.CASCADE)),
+ ],
+ )
+ changes = self.get_changes(
+ [], [author_with_m2m_through, self.publisher, contract]
+ )
+ self.assertNumberMigrations(changes, "testapp", 1)
+ self.assertNumberMigrations(changes, "contract", 1)
+ self.assertNumberMigrations(changes, "authors", 2)
+ self.assertMigrationDependencies(
+ changes,
+ "authors",
+ 1,
+ {("authors", "auto_1"), ("contract", "auto_1"), ("testapp", "auto_1")},
+ )
+ self.assertOperationTypes(changes, "testapp", 0, ["CreateModel"])
+ self.assertOperationAttributes(changes, "testapp", 0, 0, name="Publisher")
+ self.assertOperationTypes(changes, "contract", 0, ["CreateModel"])
+ self.assertOperationAttributes(changes, "contract", 0, 0, name="Contract")
+ self.assertOperationTypes(changes, "authors", 0, ["CreateModel"])
+ self.assertOperationTypes(changes, "authors", 1, ["AddField"])
+ self.assertOperationAttributes(changes, "authors", 0, 0, name="Author")
+ self.assertOperationAttributes(
+ changes, "authors", 1, 0, model_name="author", name="publishers"
+ )
+
def test_many_to_many_removed_before_through_model(self):
"""
Removing a ManyToManyField and the "through" model in the same change