mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.7.x] Fixed #22300 -- Fixed crash in migrations when changing non-relational field to relational.
Backport of 35ed792cf2 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							21eaad68e6
						
					
				
				
					commit
					b4f165fe94
				
			| @@ -267,7 +267,7 @@ class MigrationAutodetector(object): | |||||||
|             for rem_app_label, rem_model_name, rem_field_name in (old_fields - new_fields): |             for rem_app_label, rem_model_name, rem_field_name in (old_fields - new_fields): | ||||||
|                 if rem_app_label == app_label and rem_model_name == model_name: |                 if rem_app_label == app_label and rem_model_name == model_name: | ||||||
|                     old_field_dec = old_model_state.get_field_by_name(rem_field_name).deconstruct()[1:] |                     old_field_dec = old_model_state.get_field_by_name(rem_field_name).deconstruct()[1:] | ||||||
|                     if field.rel and field.rel.to: |                     if field.rel and field.rel.to and 'to' in old_field_dec[2]: | ||||||
|                         old_rel_to = old_field_dec[2]['to'] |                         old_rel_to = old_field_dec[2]['to'] | ||||||
|                         if old_rel_to in renamed_models_rel: |                         if old_rel_to in renamed_models_rel: | ||||||
|                             old_field_dec[2]['to'] = renamed_models_rel[old_rel_to] |                             old_field_dec[2]['to'] = renamed_models_rel[old_rel_to] | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ class AutodetectorTests(TestCase): | |||||||
|     author_name_default = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200, default='Ada Lovelace'))]) |     author_name_default = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200, default='Ada Lovelace'))]) | ||||||
|     author_with_book = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("book", models.ForeignKey("otherapp.Book"))]) |     author_with_book = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("book", models.ForeignKey("otherapp.Book"))]) | ||||||
|     author_renamed_with_book = ModelState("testapp", "Writer", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("book", models.ForeignKey("otherapp.Book"))]) |     author_renamed_with_book = ModelState("testapp", "Writer", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("book", models.ForeignKey("otherapp.Book"))]) | ||||||
|  |     author_with_publisher_string = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("publisher_name", models.CharField(max_length=200))]) | ||||||
|     author_with_publisher = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("publisher", models.ForeignKey("testapp.Publisher"))]) |     author_with_publisher = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("publisher", models.ForeignKey("testapp.Publisher"))]) | ||||||
|     author_with_custom_user = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("user", models.ForeignKey("thirdapp.CustomUser"))]) |     author_with_custom_user = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200)), ("user", models.ForeignKey("thirdapp.CustomUser"))]) | ||||||
|     author_proxy = ModelState("testapp", "AuthorProxy", [], {"proxy": True}, ("testapp.author", )) |     author_proxy = ModelState("testapp", "AuthorProxy", [], {"proxy": True}, ("testapp.author", )) | ||||||
| @@ -517,3 +518,25 @@ class AutodetectorTests(TestCase): | |||||||
|         action = migration.operations[0] |         action = migration.operations[0] | ||||||
|         self.assertEqual(action.__class__.__name__, "AddField") |         self.assertEqual(action.__class__.__name__, "AddField") | ||||||
|         self.assertEqual(action.name, "name") |         self.assertEqual(action.name, "name") | ||||||
|  |  | ||||||
|  |     def test_replace_string_with_foreignkey(self): | ||||||
|  |         """ | ||||||
|  |         Adding an FK in the same "spot" as a deleted CharField should work. (#22300). | ||||||
|  |         """ | ||||||
|  |         # Make state | ||||||
|  |         before = self.make_project_state([self.author_with_publisher_string]) | ||||||
|  |         after = self.make_project_state([self.author_with_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), 2) | ||||||
|  |         # Right actions? | ||||||
|  |         action = migration.operations[0] | ||||||
|  |         self.assertEqual(action.__class__.__name__, "AddField") | ||||||
|  |         self.assertEqual(action.name, "publisher") | ||||||
|  |         action = migration.operations[1] | ||||||
|  |         self.assertEqual(action.__class__.__name__, "RemoveField") | ||||||
|  |         self.assertEqual(action.name, "publisher_name") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user