Skip to content

Commit

Permalink
Fixed #28404 -- empty_value_display for fields with empty string values
Browse files Browse the repository at this point in the history
PR recommendation by @felixxm
django#17702 (comment)
  • Loading branch information
e11bits committed Jan 8, 2024
1 parent 0f8e482 commit c36dc38
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 6 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/admin/templatetags/admin_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def make_qs_param(t, n):

def _boolean_icon(field_val):
icon_url = static(
"admin/img/icon-%s.svg" % {True: "yes", False: "no", None: "unknown"}[field_val]
"admin/img/icon-%s.svg" % {True: "yes", False: "no"}.get(field_val, "unknown")
)
return format_html('<img src="{}" alt="{}">', icon_url, field_val)

Expand Down
2 changes: 1 addition & 1 deletion django/contrib/admin/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
22 changes: 22 additions & 0 deletions tests/admin_changelist/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,28 @@ def test_result_list_empty_changelist_value(self):
"Failed to find expected row element: %s" % table_output,
)

def test_result_list_empty_changelist_string_value(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.assertNotEqual(
table_output.find(row_html),
-1,
"Failed to find expected row element: %s" % table_output,
)

def test_result_list_set_empty_value_display_on_admin_site(self):
"""
Empty value display can be set on AdminSite.
Expand Down
9 changes: 6 additions & 3 deletions tests/admin_utils/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,12 @@ def test_empty_value_display_for_field(self):
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"),))
Expand Down
6 changes: 5 additions & 1 deletion tests/admin_widgets/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
UnsafeLimitChoicesTo,
VideoStream,
)
from .widgetadmin import AlbumAdmin
from .widgetadmin import site as widget_admin_site


Expand Down Expand Up @@ -639,9 +640,12 @@ def test_readonly_fields(self):
html=True,
)
response = self.client.get(reverse("admin:admin_widgets_album_add"))
empty_value_display = AlbumAdmin(
Album, widget_admin_site
).get_empty_value_display()
self.assertContains(
response,
'<div class="readonly"></div>',
'<div class="readonly">%s</div>' % empty_value_display,
html=True,
)

Expand Down

0 comments on commit c36dc38

Please sign in to comment.