diff --git a/AUTHORS b/AUTHORS index 6e54cc1ea6..d394290728 100644 --- a/AUTHORS +++ b/AUTHORS @@ -416,6 +416,7 @@ answer newbie questions, and generally made Django that much better: Himanshu Chauhan hipertracker@gmail.com Hiroki Kiyohara + Hisham Mahmood Honza Král Horst Gutmann Hugo Osvaldo Barrera diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index e8760c2931..2257b3072e 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -1026,7 +1026,9 @@ class ModelAdmin(BaseModelAdmin): """ attrs = { "class": "action-select", - "aria-label": format_html(_("Select this object for an action - {}"), obj), + "aria-label": format_html( + _("Select this object for an action - {}"), str(obj) + ), } checkbox = forms.CheckboxInput(attrs, lambda value: False) return checkbox.render(helpers.ACTION_CHECKBOX_NAME, str(obj.pk)) diff --git a/docs/releases/5.0.8.txt b/docs/releases/5.0.8.txt index 8e072049b2..1037b78f75 100644 --- a/docs/releases/5.0.8.txt +++ b/docs/releases/5.0.8.txt @@ -11,3 +11,7 @@ Bugfixes * Added missing validation for ``UniqueConstraint(nulls_distinct=False)`` when using ``*expressions`` (:ticket:`35594`). + +* Fixed a regression in Django 5.0 where ``ModelAdmin.action_checkbox`` could + break the admin changelist HTML page when rendering a model instance with a + ``__html__`` method (:ticket:`35606`). diff --git a/tests/admin_changelist/models.py b/tests/admin_changelist/models.py index 290a3ea4ec..78e65ab878 100644 --- a/tests/admin_changelist/models.py +++ b/tests/admin_changelist/models.py @@ -23,6 +23,12 @@ class GrandChild(models.Model): parent = models.ForeignKey(Child, models.SET_NULL, editable=False, null=True) name = models.CharField(max_length=30, blank=True) + def __str__(self): + return self.name + + def __html__(self): + return f'

{self.name}

' + class Genre(models.Model): name = models.CharField(max_length=20) diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index bf85cf038f..4d8845e11e 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -364,6 +364,33 @@ class ChangeListTests(TestCase): table_output, ) + def test_action_checkbox_for_model_with_dunder_html(self): + grandchild = GrandChild.objects.create(name="name") + request = self._mocked_authenticated_request("/grandchild/", self.superuser) + m = GrandChildAdmin(GrandChild, custom_site) + cl = m.get_changelist_instance(request) + cl.formset = None + template = Template( + "{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}" + ) + context = Context({"cl": cl, "opts": GrandChild._meta}) + table_output = template.render(context) + link = reverse( + "admin:admin_changelist_grandchild_change", args=(grandchild.id,) + ) + row_html = build_tbody_html( + grandchild, + link, + "name", + '-' + '-', + ) + self.assertNotEqual( + table_output.find(row_html), + -1, + "Failed to find expected row element: %s" % table_output, + ) + def test_result_list_editable_html(self): """ Regression tests for #11791: Inclusion tag result_list generates a