mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	[1.7.x] Fixed #23101: Prefer doing deletes before creates in autodetector.
Makes declined or missed renames still work (but drop data).
This commit is contained in:
		| @@ -160,15 +160,16 @@ class MigrationAutodetector(object): | ||||
|                     self.through_users[through_key] = (app_label, old_model_name, field_name) | ||||
|  | ||||
|         # Generate non-rename model operations | ||||
|         self.generate_created_models() | ||||
|         self.generate_deleted_models() | ||||
|         self.generate_created_proxies() | ||||
|         self.generate_created_models() | ||||
|         self.generate_deleted_proxies() | ||||
|         self.generate_created_proxies() | ||||
|         self.generate_altered_options() | ||||
|  | ||||
|         # Generate field operations | ||||
|         self.generate_added_fields() | ||||
|         self.generate_renamed_fields() | ||||
|         self.generate_removed_fields() | ||||
|         self.generate_added_fields() | ||||
|         self.generate_altered_fields() | ||||
|         self.generate_altered_unique_together() | ||||
|         self.generate_altered_index_together() | ||||
| @@ -682,17 +683,17 @@ class MigrationAutodetector(object): | ||||
|                 ), | ||||
|             ) | ||||
|  | ||||
|     def generate_added_fields(self): | ||||
|         # New fields | ||||
|     def generate_renamed_fields(self): | ||||
|         """ | ||||
|         Works out renamed fields | ||||
|         """ | ||||
|         self.renamed_fields = {} | ||||
|         for app_label, model_name, field_name in sorted(self.new_field_keys - self.old_field_keys): | ||||
|             old_model_name = self.renamed_models.get((app_label, model_name), model_name) | ||||
|             old_model_state = self.from_state.models[app_label, old_model_name] | ||||
|             new_model_state = self.to_state.models[app_label, model_name] | ||||
|             field = self.new_apps.get_model(app_label, model_name)._meta.get_field_by_name(field_name)[0] | ||||
|             # Scan to see if this is actually a rename! | ||||
|             field_dec = self.deep_deconstruct(field) | ||||
|             found_rename = False | ||||
|             for rem_app_label, rem_model_name, rem_field_name in sorted(self.old_field_keys - self.new_field_keys): | ||||
|                 if rem_app_label == app_label and rem_model_name == model_name: | ||||
|                     old_field_dec = self.deep_deconstruct(old_model_state.get_field_by_name(rem_field_name)) | ||||
| @@ -713,10 +714,15 @@ class MigrationAutodetector(object): | ||||
|                             self.old_field_keys.remove((rem_app_label, rem_model_name, rem_field_name)) | ||||
|                             self.old_field_keys.add((app_label, model_name, field_name)) | ||||
|                             self.renamed_fields[app_label, model_name, field_name] = rem_field_name | ||||
|                             found_rename = True | ||||
|                             break | ||||
|             if found_rename: | ||||
|                 continue | ||||
|  | ||||
|  | ||||
|     def generate_added_fields(self): | ||||
|         """ | ||||
|         Fields that have been added | ||||
|         """ | ||||
|         for app_label, model_name, field_name in sorted(self.new_field_keys - self.old_field_keys): | ||||
|             field = self.new_apps.get_model(app_label, model_name)._meta.get_field_by_name(field_name)[0] | ||||
|             # Fields that are foreignkeys/m2ms depend on stuff | ||||
|             dependencies = [] | ||||
|             if field.rel and field.rel.to: | ||||
|   | ||||
| @@ -276,16 +276,10 @@ class AutodetectorTests(TestCase): | ||||
|         after = self.make_project_state([self.author_name_renamed]) | ||||
|         autodetector = MigrationAutodetector(before, after, MigrationQuestioner({"ask_rename": True})) | ||||
|         changes = autodetector._detect_changes() | ||||
|         # Right number of migrations? | ||||
|         self.assertEqual(len(changes['testapp']), 1) | ||||
|         # Right number of actions? | ||||
|         migration = changes['testapp'][0] | ||||
|         self.assertEqual(len(migration.operations), 1) | ||||
|         # Right action? | ||||
|         action = migration.operations[0] | ||||
|         self.assertEqual(action.__class__.__name__, "RenameField") | ||||
|         self.assertEqual(action.old_name, "name") | ||||
|         self.assertEqual(action.new_name, "names") | ||||
|         # Check | ||||
|         self.assertNumberMigrations(changes, 'testapp', 1) | ||||
|         self.assertOperationTypes(changes, 'testapp', 0, ["RenameField"]) | ||||
|         self.assertOperationAttributes(changes, 'testapp', 0, 0, old_name="name", new_name="names") | ||||
|  | ||||
|     def test_rename_model(self): | ||||
|         "Tests autodetection of renamed models" | ||||
| @@ -719,21 +713,12 @@ class AutodetectorTests(TestCase): | ||||
|         after = self.make_project_state([self.author_with_publisher, self.publisher]) | ||||
|         autodetector = MigrationAutodetector(before, after) | ||||
|         changes = autodetector._detect_changes() | ||||
|         # Right number of migrations? | ||||
|         self.assertEqual(len(changes['testapp']), 1) | ||||
|         # Right number of actions? | ||||
|         migration = changes['testapp'][0] | ||||
|         self.assertEqual(len(migration.operations), 3) | ||||
|         # Right actions? | ||||
|         action = migration.operations[0] | ||||
|         self.assertEqual(action.__class__.__name__, "CreateModel") | ||||
|         self.assertEqual(action.name, "Publisher") | ||||
|         action = migration.operations[1] | ||||
|         self.assertEqual(action.__class__.__name__, "AddField") | ||||
|         self.assertEqual(action.name, "publisher") | ||||
|         action = migration.operations[2] | ||||
|         self.assertEqual(action.__class__.__name__, "RemoveField") | ||||
|         self.assertEqual(action.name, "publisher_name") | ||||
|         # Right result? | ||||
|         self.assertNumberMigrations(changes, 'testapp', 1) | ||||
|         self.assertOperationTypes(changes, 'testapp', 0, ["CreateModel", "RemoveField", "AddField"]) | ||||
|         self.assertOperationAttributes(changes, 'testapp', 0, 0, name="Publisher") | ||||
|         self.assertOperationAttributes(changes, 'testapp', 0, 1, name="publisher_name") | ||||
|         self.assertOperationAttributes(changes, 'testapp', 0, 2, name="publisher") | ||||
|  | ||||
|     def test_foreign_key_removed_before_target_model(self): | ||||
|         """ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user