[Django] #36791: Migration does not drop old M2M through-table when ManyToManyField target model changes

10 views
Skip to first unread message

Django

unread,
Dec 10, 2025, 7:39:01 PM (6 days ago) Dec 10
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Type:
Amoateng | Uncategorized
Status: new | Component: Database
| layer (models, ORM)
Version: 6.0 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
When changing the target model of a ManyToManyField, the migration
autodetector generates only an AlterField operation. Django does not
create a RemoveField + AddField sequence, and the old automatically
generated through-table is left in place.

This results in the database schema no longer matching the model
definitions. In my case, the stale through-table caused inconsistent M2M
behaviour and errors when interacting with the relationship. No data
records were lost, but the schema was incorrect until manually fixed.

This behaviour appears inconsistent with how Django handles other
destructive schema changes.
--
Ticket URL: <https://code.djangoproject.com/ticket/36791>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 11, 2025, 4:34:00 PM (5 days ago) Dec 11
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: (none)
Amoateng |
Type: Bug | Status: new
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* component: Database layer (models, ORM) => Migrations
* stage: Unreviewed => Accepted
* type: Uncategorized => Bug

Comment:

Thanks, replicated. Patch looks straightforward, would you be willing to
submit a PR and extrapolate from similar existing test cases?

{{{#!diff
diff --git a/django/db/migrations/autodetector.py
b/django/db/migrations/autodetector.py
index 7cc22c0637..fca73a675d 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -1339,7 +1339,8 @@ class MigrationAutodetector:
if old_field_dec != new_field_dec and old_field_name ==
field_name:
both_m2m = old_field.many_to_many and
new_field.many_to_many
neither_m2m = not old_field.many_to_many and not
new_field.many_to_many
- if both_m2m or neither_m2m:
+ target_changed = both_m2m and new_field_dec[2]["to"] !=
old_field_dec[2]["to"]
+ if (both_m2m or neither_m2m) and not target_changed:
# Either both fields are m2m or neither is
preserve_default = True
if (
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:1>

Django

unread,
Dec 11, 2025, 5:38:10 PM (5 days ago) Dec 11
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: (none)
Amoateng |
Type: Bug | Status: new
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Johanan Oppong Amoateng):

Yes please i will submit a patch for this
--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:2>

Django

unread,
Dec 11, 2025, 5:39:19 PM (5 days ago) Dec 11
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Johanan Oppong Amoateng):

* owner: (none) => Johanan Oppong Amoateng
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:3>

Django

unread,
Dec 12, 2025, 6:21:38 PM (4 days ago) Dec 12
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Johanan Oppong Amoateng):

* has_patch: 0 => 1

Comment:

https://github.com/django/django/pull/20395
--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:4>

Django

unread,
Dec 14, 2025, 5:10:54 AM (2 days ago) Dec 14
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Clifford Gama):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:5>

Django

unread,
Dec 14, 2025, 9:11:39 AM (2 days ago) Dec 14
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Johanan Oppong Amoateng):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:6>

Django

unread,
Dec 14, 2025, 1:49:10 PM (2 days ago) Dec 14
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Clifford Gama):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:7>

Django

unread,
Dec 15, 2025, 8:25:24 AM (yesterday) Dec 15
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Clifford Gama):

* stage: Ready for checkin => Accepted

--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:8>

Django

unread,
12:36 PM (2 hours ago) 12:36 PM
to django-...@googlegroups.com
#36791: Migration does not drop old M2M through-table when ManyToManyField target
model changes
-------------------------------------+-------------------------------------
Reporter: Johanan Oppong | Owner: Johanan
Amoateng | Oppong Amoateng
Type: Bug | Status: assigned
Component: Migrations | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36791#comment:9>
Reply all
Reply to author
Forward
0 new messages