Fixed #24725 -- Allowed renaming of target models in ManyToMany relations
This is a regression caused by introducing rendered migration states in1aa3e09c20
and the _meta refactoring infb48eb0581
. Thanks to Danilo Bargen for reporting the issue and Marten Kenbeek and Tim Graham for triaging the bug and providing the initial test case.
This commit is contained in:
parent
cf34ee68f0
commit
63f9b633f9
|
@ -161,7 +161,7 @@ class RenameModel(Operation):
|
||||||
# Get all of the related objects we need to repoint
|
# Get all of the related objects we need to repoint
|
||||||
all_related_objects = (
|
all_related_objects = (
|
||||||
f for f in model._meta.get_fields(include_hidden=True)
|
f for f in model._meta.get_fields(include_hidden=True)
|
||||||
if f.auto_created and not f.concrete and not (f.hidden or f.many_to_many)
|
if f.auto_created and not f.concrete and (not f.hidden or f.many_to_many)
|
||||||
)
|
)
|
||||||
# Rename the model
|
# Rename the model
|
||||||
state.models[app_label, self.new_name_lower] = state.models[app_label, self.old_name_lower]
|
state.models[app_label, self.new_name_lower] = state.models[app_label, self.old_name_lower]
|
||||||
|
|
|
@ -72,6 +72,9 @@ Bugfixes
|
||||||
* Restored the ability to use iterators as queryset filter arguments
|
* Restored the ability to use iterators as queryset filter arguments
|
||||||
(:ticket:`24719`).
|
(:ticket:`24719`).
|
||||||
|
|
||||||
|
* Fixed a migration crash when renaming the target model of a many-to-many
|
||||||
|
relation (:ticket:`24725`).
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
@ -614,6 +614,32 @@ class OperationTests(OperationTestBase):
|
||||||
self.assertEqual(Rider.objects.count(), 2)
|
self.assertEqual(Rider.objects.count(), 2)
|
||||||
self.assertEqual(Pony._meta.get_field('riders').remote_field.through.objects.count(), 2)
|
self.assertEqual(Pony._meta.get_field('riders').remote_field.through.objects.count(), 2)
|
||||||
|
|
||||||
|
def test_rename_m2m_target_model(self):
|
||||||
|
app_label = "test_rename_m2m_target_model"
|
||||||
|
project_state = self.apply_operations(app_label, ProjectState(), operations=[
|
||||||
|
migrations.CreateModel("Rider", fields=[]),
|
||||||
|
migrations.CreateModel("Pony", fields=[
|
||||||
|
("riders", models.ManyToManyField("Rider")),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
Pony = project_state.apps.get_model(app_label, "Pony")
|
||||||
|
Rider = project_state.apps.get_model(app_label, "Rider")
|
||||||
|
pony = Pony.objects.create()
|
||||||
|
rider = Rider.objects.create()
|
||||||
|
pony.riders.add(rider)
|
||||||
|
|
||||||
|
project_state = self.apply_operations(app_label, project_state, operations=[
|
||||||
|
migrations.RenameModel("Rider", "Rider2"),
|
||||||
|
])
|
||||||
|
Pony = project_state.apps.get_model(app_label, "Pony")
|
||||||
|
Rider = project_state.apps.get_model(app_label, "Rider2")
|
||||||
|
pony = Pony.objects.create()
|
||||||
|
rider = Rider.objects.create()
|
||||||
|
pony.riders.add(rider)
|
||||||
|
self.assertEqual(Pony.objects.count(), 2)
|
||||||
|
self.assertEqual(Rider.objects.count(), 2)
|
||||||
|
self.assertEqual(Pony._meta.get_field('riders').remote_field.through.objects.count(), 2)
|
||||||
|
|
||||||
def test_add_field(self):
|
def test_add_field(self):
|
||||||
"""
|
"""
|
||||||
Tests the AddField operation.
|
Tests the AddField operation.
|
||||||
|
|
Loading…
Reference in New Issue