mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #26088 -- Made autodector detect changing proxy model to MTI.
This commit is contained in:
		| @@ -612,6 +612,20 @@ class MigrationAutodetector(object): | ||||
|                     ] | ||||
|                 ) | ||||
|  | ||||
|             # Fix relationships if the model changed from a proxy model to a | ||||
|             # concrete model. | ||||
|             if (app_label, model_name) in self.old_proxy_keys: | ||||
|                 for related_object in model_opts.related_objects: | ||||
|                     self.add_operation( | ||||
|                         related_object.related_model._meta.app_label, | ||||
|                         operations.AlterField( | ||||
|                             model_name=related_object.related_model._meta.object_name, | ||||
|                             name=related_object.field.name, | ||||
|                             field=related_object.field, | ||||
|                         ), | ||||
|                         dependencies=[(app_label, model_name, None, True)], | ||||
|                     ) | ||||
|  | ||||
|     def generate_created_proxies(self): | ||||
|         """ | ||||
|         Makes CreateModel statements for proxy models. | ||||
|   | ||||
| @@ -240,6 +240,7 @@ class AutodetectorTests(TestCase): | ||||
|     }, ("testapp.author", )) | ||||
|     author_proxy_notproxy = ModelState("testapp", "AuthorProxy", [], {}, ("testapp.author", )) | ||||
|     author_proxy_third = ModelState("thirdapp", "AuthorProxy", [], {"proxy": True}, ("testapp.author", )) | ||||
|     author_proxy_third_notproxy = ModelState("thirdapp", "AuthorProxy", [], {}, ("testapp.author", )) | ||||
|     author_proxy_proxy = ModelState("testapp", "AAuthorProxyProxy", [], {"proxy": True}, ("testapp.authorproxy", )) | ||||
|     author_unmanaged = ModelState("testapp", "AuthorUnmanaged", [], {"managed": False}, ("testapp.author", )) | ||||
|     author_unmanaged_managed = ModelState("testapp", "AuthorUnmanaged", [], {}, ("testapp.author", )) | ||||
| @@ -336,6 +337,10 @@ class AutodetectorTests(TestCase): | ||||
|         ("author", models.ForeignKey("thirdapp.AuthorProxy", models.CASCADE)), | ||||
|         ("title", models.CharField(max_length=200)), | ||||
|     ]) | ||||
|     book_proxy_proxy_fk = ModelState("otherapp", "Book", [ | ||||
|         ("id", models.AutoField(primary_key=True)), | ||||
|         ("author", models.ForeignKey("testapp.AAuthorProxyProxy", models.CASCADE)), | ||||
|     ]) | ||||
|     book_migrations_fk = ModelState("otherapp", "Book", [ | ||||
|         ("id", models.AutoField(primary_key=True)), | ||||
|         ("author", models.ForeignKey("migrations.UnmigratedModel", models.CASCADE)), | ||||
| @@ -1291,6 +1296,73 @@ class AutodetectorTests(TestCase): | ||||
|         # The field name the FK on the book model points to | ||||
|         self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'pk_field') | ||||
|  | ||||
|     def test_proxy_to_mti_with_fk_to_proxy(self): | ||||
|         # First, test the pk table and field name. | ||||
|         changes = self.get_changes( | ||||
|             [], | ||||
|             [self.author_empty, self.author_proxy_third, self.book_proxy_fk], | ||||
|         ) | ||||
|         self.assertEqual( | ||||
|             changes['otherapp'][0].operations[0].fields[2][1].remote_field.model._meta.db_table, | ||||
|             'testapp_author', | ||||
|         ) | ||||
|         self.assertEqual(changes['otherapp'][0].operations[0].fields[2][1].remote_field.field_name, 'id') | ||||
|  | ||||
|         # Change AuthorProxy to use MTI. | ||||
|         changes = self.get_changes( | ||||
|             [self.author_empty, self.author_proxy_third, self.book_proxy_fk], | ||||
|             [self.author_empty, self.author_proxy_third_notproxy, self.book_proxy_fk], | ||||
|         ) | ||||
|         # Right number/type of migrations for the AuthorProxy model? | ||||
|         self.assertNumberMigrations(changes, 'thirdapp', 1) | ||||
|         self.assertOperationTypes(changes, 'thirdapp', 0, ['DeleteModel', 'CreateModel']) | ||||
|         # Right number/type of migrations for the Book model with a FK to | ||||
|         # AuthorProxy? | ||||
|         self.assertNumberMigrations(changes, 'otherapp', 1) | ||||
|         self.assertOperationTypes(changes, 'otherapp', 0, ['AlterField']) | ||||
|         # otherapp should depend on thirdapp. | ||||
|         self.assertMigrationDependencies(changes, 'otherapp', 0, [('thirdapp', 'auto_1')]) | ||||
|         # Now, test the pk table and field name. | ||||
|         self.assertEqual( | ||||
|             changes['otherapp'][0].operations[0].field.remote_field.model._meta.db_table, | ||||
|             'thirdapp_authorproxy', | ||||
|         ) | ||||
|         self.assertEqual(changes['otherapp'][0].operations[0].field.remote_field.field_name, 'author_ptr') | ||||
|  | ||||
|     def test_proxy_to_mti_with_fk_to_proxy_proxy(self): | ||||
|         # First, test the pk table and field name. | ||||
|         changes = self.get_changes( | ||||
|             [], | ||||
|             [self.author_empty, self.author_proxy, self.author_proxy_proxy, self.book_proxy_proxy_fk], | ||||
|         ) | ||||
|         self.assertEqual( | ||||
|             changes['otherapp'][0].operations[0].fields[1][1].remote_field.model._meta.db_table, | ||||
|             'testapp_author', | ||||
|         ) | ||||
|         self.assertEqual(changes['otherapp'][0].operations[0].fields[1][1].remote_field.field_name, 'id') | ||||
|  | ||||
|         # Change AuthorProxy to use MTI. FK still points to AAuthorProxyProxy, | ||||
|         # a proxy of AuthorProxy. | ||||
|         changes = self.get_changes( | ||||
|             [self.author_empty, self.author_proxy, self.author_proxy_proxy, self.book_proxy_proxy_fk], | ||||
|             [self.author_empty, self.author_proxy_notproxy, self.author_proxy_proxy, self.book_proxy_proxy_fk], | ||||
|         ) | ||||
|         # Right number/type of migrations for the AuthorProxy model? | ||||
|         self.assertNumberMigrations(changes, 'testapp', 1) | ||||
|         self.assertOperationTypes(changes, 'testapp', 0, ['DeleteModel', 'CreateModel']) | ||||
|         # Right number/type of migrations for the Book model with a FK to | ||||
|         # AAuthorProxyProxy? | ||||
|         self.assertNumberMigrations(changes, 'otherapp', 1) | ||||
|         self.assertOperationTypes(changes, 'otherapp', 0, ['AlterField']) | ||||
|         # otherapp should depend on testapp. | ||||
|         self.assertMigrationDependencies(changes, 'otherapp', 0, [('testapp', 'auto_1')]) | ||||
|         # Now, test the pk table and field name. | ||||
|         self.assertEqual( | ||||
|             changes['otherapp'][0].operations[0].field.remote_field.model._meta.db_table, | ||||
|             'testapp_authorproxy', | ||||
|         ) | ||||
|         self.assertEqual(changes['otherapp'][0].operations[0].field.remote_field.field_name, 'author_ptr') | ||||
|  | ||||
|     def test_unmanaged_create(self): | ||||
|         """Tests that the autodetector correctly deals with managed models.""" | ||||
|         # First, we test adding an unmanaged model | ||||
|   | ||||
		Reference in New Issue
	
	Block a user