|
6 | 6 | from django.contrib import admin |
7 | 7 | from django.contrib.contenttypes.models import ContentType |
8 | 8 | from django.utils.html import escape |
| 9 | +from django.test import RequestFactory |
| 10 | +from django.urls import resolve |
9 | 11 |
|
10 | 12 | from django.contrib.staticfiles.testing import StaticLiveServerTestCase |
11 | 13 |
|
@@ -105,6 +107,118 @@ def test_get_child_inlines(self): |
105 | 107 | self.assertEqual(child_inlines[0], Inline.InlineModelAChild) |
106 | 108 | self.assertEqual(child_inlines[1], Inline.InlineModelBChild) |
107 | 109 |
|
| 110 | + def test_show_in_index(self): |
| 111 | + """ |
| 112 | + Test that show_in_index=False hides the model from the index and sidebar. |
| 113 | + """ |
| 114 | + |
| 115 | + @self.register(Model2A) |
| 116 | + class Model2Admin(PolymorphicParentModelAdmin): |
| 117 | + base_model = Model2A |
| 118 | + child_models = (Model2B,) |
| 119 | + |
| 120 | + @self.register(Model2B) |
| 121 | + class Model2BChildAdmin(PolymorphicChildModelAdmin): |
| 122 | + base_model = Model2A |
| 123 | + show_in_index = False |
| 124 | + |
| 125 | + @self.register(Model2C) |
| 126 | + class Model2CChildAdmin(PolymorphicChildModelAdmin): |
| 127 | + base_model = Model2A |
| 128 | + show_in_index = True |
| 129 | + |
| 130 | + # Case 1: Index Page (url_name="index") |
| 131 | + request = self.create_admin_request("get", "/tmp-admin/") |
| 132 | + app_list = self.admin_site.get_app_list(request) |
| 133 | + |
| 134 | + # Check that Model2B is NOT present |
| 135 | + found_model2b = any( |
| 136 | + model["object_name"] == "Model2B" for app in app_list for model in app["models"] |
| 137 | + ) |
| 138 | + self.assertFalse(found_model2b, "Child model should be hidden in index (Issue #532)") |
| 139 | + |
| 140 | + found_model2c = any( |
| 141 | + model["object_name"] == "Model2C" for app in app_list for model in app["models"] |
| 142 | + ) |
| 143 | + self.assertTrue(found_model2c, "Child model should be visible in sidebar on change page") |
| 144 | + |
| 145 | + # Case 2: Change Page (url_name="change") - Simulating Sidebar (Issue #497) |
| 146 | + # We need a URL that resolves to a change view to test the sidebar context. |
| 147 | + change_url = "/tmp-admin/polymorphic/model2a/1/change/" |
| 148 | + request = self.create_admin_request("get", change_url) |
| 149 | + app_list = self.admin_site.get_app_list(request) |
| 150 | + |
| 151 | + found_model2b = any( |
| 152 | + model["object_name"] == "Model2B" for app in app_list for model in app["models"] |
| 153 | + ) |
| 154 | + found_model2c = any( |
| 155 | + model["object_name"] == "Model2C" for app in app_list for model in app["models"] |
| 156 | + ) |
| 157 | + self.assertFalse( |
| 158 | + found_model2b, "Child model should be hidden in sidebar on change page (Issue #497)" |
| 159 | + ) |
| 160 | + self.assertTrue(found_model2c, "Child model should be visible in sidebar on change page") |
| 161 | + |
| 162 | + def test_show_in_index_custom_site(self): |
| 163 | + """ |
| 164 | + Test that show_in_index=False works correctly with a custom AdminSite. |
| 165 | + """ |
| 166 | + original_name = self.admin_site.name |
| 167 | + try: |
| 168 | + # Change the site name to simulate a custom site |
| 169 | + self.admin_site.name = "custom_admin" |
| 170 | + |
| 171 | + # Register the model |
| 172 | + @self.register(Model2B) |
| 173 | + class Model2ChildAdmin(PolymorphicChildModelAdmin): |
| 174 | + base_model = Model2A |
| 175 | + show_in_index = False |
| 176 | + |
| 177 | + # Re-set URLConf to update patterns with new name |
| 178 | + from django.urls import clear_url_caches, set_urlconf, path, resolve |
| 179 | + |
| 180 | + clear_url_caches() |
| 181 | + set_urlconf(tuple([path("tmp-admin/", self.admin_site.urls)])) |
| 182 | + |
| 183 | + request = self.create_admin_request("get", "/tmp-admin/") |
| 184 | + |
| 185 | + # Verify resolving matches namespace 'custom_admin' |
| 186 | + match = resolve("/tmp-admin/") |
| 187 | + assert match.namespace == "custom_admin" |
| 188 | + |
| 189 | + # Now check app list |
| 190 | + app_list = self.admin_site.get_app_list(request) |
| 191 | + |
| 192 | + found_model2b = any( |
| 193 | + model["object_name"] == "Model2B" for app in app_list for model in app["models"] |
| 194 | + ) |
| 195 | + self.assertFalse(found_model2b, "Child model should be hidden in Custom Admin Site") |
| 196 | + |
| 197 | + finally: |
| 198 | + self.admin_site.name = original_name |
| 199 | + |
| 200 | + def test_get_model_perms_hidden(self): |
| 201 | + # Register a child admin with show_in_index=False |
| 202 | + @self.register(Model2B) |
| 203 | + class Model2ChildAdmin(PolymorphicChildModelAdmin): |
| 204 | + base_model = Model2A |
| 205 | + show_in_index = False |
| 206 | + |
| 207 | + # Simulate a request to the admin index |
| 208 | + factory = RequestFactory() |
| 209 | + request = factory.get("/tmp-admin/") |
| 210 | + match = resolve("/tmp-admin/") |
| 211 | + |
| 212 | + # Ensure namespace matches admin site |
| 213 | + match.namespace = self.admin_site.name |
| 214 | + request._resolver_match = match |
| 215 | + |
| 216 | + # Call get_model_perms directly |
| 217 | + perms = Model2ChildAdmin(Model2B, self.admin_site).get_model_perms(request) |
| 218 | + |
| 219 | + # Assert that all perms are False |
| 220 | + assert perms == {"add": False, "change": False, "delete": False} |
| 221 | + |
108 | 222 | def test_admin_inlines(self): |
109 | 223 | """ |
110 | 224 | Test the registration of inline models. |
|
0 commit comments