diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index f466614061..7a5551f650 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -594,6 +594,12 @@ class ModelAdmin(BaseModelAdmin): def __str__(self): return "%s.%s" % (self.model._meta.app_label, self.__class__.__name__) + def __repr__(self): + return ( + f'<{self.__class__.__qualname__}: model={self.model.__qualname__} ' + f'site={self.admin_site!r}>' + ) + def get_inline_instances(self, request, obj=None): inline_instances = [] for inline_class in self.get_inlines(request, obj): diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 62c5c8a782..a87bac02bd 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -77,6 +77,9 @@ class AdminSite: self._global_actions = self._actions.copy() all_sites.add(self) + def __repr__(self): + return f'{self.__class__.__name__}(name={self.name!r})' + def check(self, app_configs): """ Run the system checks on all ModelAdmins, except if they aren't @@ -561,6 +564,9 @@ class DefaultAdminSite(LazyObject): AdminSiteClass = import_string(apps.get_app_config('admin').default_site) self._wrapped = AdminSiteClass() + def __repr__(self): + return repr(self._wrapped) + # This global object represents the default admin site, for the common case. # You can provide your own AdminSite using the (Simple)AdminConfig.default_site diff --git a/tests/admin_default_site/tests.py b/tests/admin_default_site/tests.py index 5d05ec9c45..9ce087549f 100644 --- a/tests/admin_default_site/tests.py +++ b/tests/admin_default_site/tests.py @@ -2,6 +2,8 @@ from django.contrib import admin from django.contrib.admin import sites from django.test import SimpleTestCase, override_settings +from .sites import CustomAdminSite + @override_settings(INSTALLED_APPS=[ 'admin_default_site.apps.MyCustomAdminConfig', @@ -29,3 +31,13 @@ class CustomAdminSiteTests(SimpleTestCase): class DefaultAdminSiteTests(SimpleTestCase): def test_use_default_admin_site(self): self.assertEqual(admin.site.__class__.__name__, 'AdminSite') + + def test_repr(self): + self.assertEqual(str(admin.site), "AdminSite(name='admin')") + self.assertEqual(repr(admin.site), "AdminSite(name='admin')") + + +class AdminSiteTests(SimpleTestCase): + def test_repr(self): + admin_site = CustomAdminSite(name='other') + self.assertEqual(repr(admin_site), "CustomAdminSite(name='other')") diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 00de9f7523..42cc369a9e 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -722,6 +722,13 @@ class ModelAdminTests(TestCase): self.assertEqual(perms_needed, {'band'}) self.assertEqual(protected, []) + def test_modeladmin_repr(self): + ma = ModelAdmin(Band, self.site) + self.assertEqual( + repr(ma), + "", + ) + class ModelAdminPermissionTests(SimpleTestCase):