Fixed #24725 -- Allowed renaming of target models in ManyToMany relations

This is a regression caused by introducing rendered migration states in
1aa3e09c20 and the _meta refactoring in fb48eb0581.

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:
Markus Holtermann 2015-04-30 01:39:50 +02:00
parent cf34ee68f0
commit 63f9b633f9
3 changed files with 30 additions and 1 deletions

View File

@ -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]

View File

@ -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
============= =============

View File

@ -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.