diff options
| author | Alexander Lazarević <laza@e11bits.com> | 2024-01-08 15:47:09 +0700 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2024-01-10 08:34:25 +0100 |
| commit | 9b02ad91ead3db75036be981bab2083aebc993a6 (patch) | |
| tree | 99fab6b743eb7ec79ae09045c4f11ba95a0c785a | |
| parent | ec7651586d2d94e1ccd8f905c6a3776ad936b62d (diff) | |
Fixed #28404 -- Made displaying values in admin respect Field's empty_values.
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/contrib/admin/utils.py | 2 | ||||
| -rw-r--r-- | tests/admin_changelist/tests.py | 34 | ||||
| -rw-r--r-- | tests/admin_utils/tests.py | 9 | ||||
| -rw-r--r-- | tests/admin_widgets/tests.py | 2 |
5 files changed, 37 insertions, 11 deletions
@@ -47,6 +47,7 @@ answer newbie questions, and generally made Django that much better: Aleksandra Sendecka <asendecka@hauru.eu> Aleksi Häkli <aleksi.hakli@iki.fi> Alex Dutton <django@alexdutton.co.uk> + Alexander Lazarević <laza@e11bits.com> Alexander Myodov <alex@myodov.com> Alexandr Tatarinov <tatarinov.dev@gmail.com> Alex Aktsipetrov <alex.akts@gmail.com> diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index d6c54dd440..97a09143ad 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -433,7 +433,7 @@ def display_for_field(value, field, empty_value_display): # general null test. elif isinstance(field, models.BooleanField): return _boolean_icon(value) - elif value is None: + elif value in field.empty_values: return empty_value_display elif isinstance(field, models.DateTimeField): return formats.localize(timezone.template_localtime(value)) diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 4870d9bbe9..b4739b572d 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -74,15 +74,15 @@ from .models import ( ) -def build_tbody_html(obj, href, extra_fields): +def build_tbody_html(obj, href, field_name, extra_fields): return ( "<tbody><tr>" '<td class="action-checkbox">' '<input type="checkbox" name="_selected_action" value="{}" ' 'class="action-select" aria-label="Select this object for an action - {}"></td>' - '<th class="field-name"><a href="{}">name</a></th>' + '<th class="field-name"><a href="{}">{}</a></th>' "{}</tr></tbody>" - ).format(obj.pk, str(obj), href, extra_fields) + ).format(obj.pk, str(obj), href, field_name, extra_fields) @override_settings(ROOT_URLCONF="admin_changelist.urls") @@ -245,7 +245,7 @@ class ChangeListTests(TestCase): table_output = template.render(context) link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) row_html = build_tbody_html( - new_child, link, '<td class="field-parent nowrap">-</td>' + new_child, link, "name", '<td class="field-parent nowrap">-</td>' ) self.assertNotEqual( table_output.find(row_html), @@ -253,6 +253,24 @@ class ChangeListTests(TestCase): "Failed to find expected row element: %s" % table_output, ) + def test_result_list_empty_changelist_value_blank_string(self): + new_child = Child.objects.create(name="", parent=None) + request = self.factory.get("/child/") + request.user = self.superuser + m = ChildAdmin(Child, 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": Child._meta}) + table_output = template.render(context) + link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) + row_html = build_tbody_html( + new_child, link, "-", '<td class="field-parent nowrap">-</td>' + ) + self.assertInHTML(row_html, table_output) + def test_result_list_set_empty_value_display_on_admin_site(self): """ Empty value display can be set on AdminSite. @@ -272,7 +290,7 @@ class ChangeListTests(TestCase): table_output = template.render(context) link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) row_html = build_tbody_html( - new_child, link, '<td class="field-parent nowrap">???</td>' + new_child, link, "name", '<td class="field-parent nowrap">???</td>' ) self.assertNotEqual( table_output.find(row_html), @@ -299,6 +317,7 @@ class ChangeListTests(TestCase): row_html = build_tbody_html( new_child, link, + "name", '<td class="field-age_display">&dagger;</td>' '<td class="field-age">-empty-</td>', ) @@ -327,7 +346,10 @@ class ChangeListTests(TestCase): table_output = template.render(context) link = reverse("admin:admin_changelist_child_change", args=(new_child.id,)) row_html = build_tbody_html( - new_child, link, '<td class="field-parent nowrap">%s</td>' % new_parent + new_child, + link, + "name", + '<td class="field-parent nowrap">%s</td>' % new_parent, ) self.assertNotEqual( table_output.find(row_html), diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py index 582ed23b4d..393770bd2d 100644 --- a/tests/admin_utils/tests.py +++ b/tests/admin_utils/tests.py @@ -159,9 +159,12 @@ class UtilsTests(SimpleTestCase): models.TimeField(), ] for model_field in tests: - with self.subTest(model_field=model_field): - display_value = display_for_field(None, model_field, self.empty_value) - self.assertEqual(display_value, self.empty_value) + for value in model_field.empty_values: + with self.subTest(model_field=model_field, empty_value=value): + display_value = display_for_field( + value, model_field, self.empty_value + ) + self.assertEqual(display_value, self.empty_value) def test_empty_value_display_choices(self): model_field = models.CharField(choices=((None, "test_none"),)) diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index d497599435..50c26095ff 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -641,7 +641,7 @@ class AdminFileWidgetTests(TestDataMixin, TestCase): response = self.client.get(reverse("admin:admin_widgets_album_add")) self.assertContains( response, - '<div class="readonly"></div>', + '<div class="readonly">-</div>', html=True, ) |
