From 58d357fc65ab0d3b16184db81059b9cef3b83c10 Mon Sep 17 00:00:00 2001
From: Hameed Gifford <giff.h92@gmail.com>
Date: Tue, 8 Mar 2022 00:22:03 -0500
Subject: [PATCH] Fixed #33563 -- Fixed contenttype reverse data migration
 crash with a multiple databases setup.

---
 .../0002_remove_content_type_name.py          |  3 +-
 tests/contenttypes_tests/test_migrations.py   | 31 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 tests/contenttypes_tests/test_migrations.py

diff --git a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py
index 3bee3a864f..cb026e7503 100644
--- a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py
+++ b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py
@@ -2,8 +2,9 @@ from django.db import migrations, models
 
 
 def add_legacy_name(apps, schema_editor):
+    alias = schema_editor.connection.alias
     ContentType = apps.get_model("contenttypes", "ContentType")
-    for ct in ContentType.objects.all():
+    for ct in ContentType.objects.using(alias):
         try:
             ct.name = apps.get_model(ct.app_label, ct.model)._meta.object_name
         except LookupError:
diff --git a/tests/contenttypes_tests/test_migrations.py b/tests/contenttypes_tests/test_migrations.py
new file mode 100644
index 0000000000..7482473c98
--- /dev/null
+++ b/tests/contenttypes_tests/test_migrations.py
@@ -0,0 +1,31 @@
+from importlib import import_module
+
+from django.apps import apps
+from django.contrib.auth.models import Permission
+from django.contrib.contenttypes.models import ContentType
+from django.db import DEFAULT_DB_ALIAS, connections
+from django.test import TransactionTestCase
+
+remove_content_type_name = import_module(
+    "django.contrib.contenttypes.migrations.0002_remove_content_type_name"
+)
+
+
+class MultiDBRemoveContentTypeNameTests(TransactionTestCase):
+    databases = {"default", "other"}
+    available_apps = ["django.contrib.auth", "django.contrib.contenttypes"]
+
+    def test_add_legacy_name_other_database(self):
+        # add_legacy_name() should update ContentType objects in the specified
+        # database. Remove ContentTypes from the default database to distinct
+        # from which database they are fetched.
+        Permission.objects.all().delete()
+        ContentType.objects.all().delete()
+        # ContentType.name in the current version is a property and cannot be
+        # set, so an AttributeError is raised with the other database.
+        with self.assertRaises(AttributeError):
+            with connections["other"].schema_editor() as editor:
+                remove_content_type_name.add_legacy_name(apps, editor)
+        # ContentType were removed from the default database.
+        with connections[DEFAULT_DB_ALIAS].schema_editor() as editor:
+            remove_content_type_name.add_legacy_name(apps, editor)