diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index 220b60e1dc..db58af9f2c 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -156,7 +156,11 @@ def items_for_result(cl, result, form): if value is None: result_repr = EMPTY_CHANGELIST_VALUE if isinstance(f.rel, models.ManyToOneRel): - result_repr = escape(getattr(result, f.name)) + field_val = getattr(result, f.name) + if field_val is None: + result_repr = EMPTY_CHANGELIST_VALUE + else: + result_repr = escape(field_val) else: result_repr = display_for_field(value, f) if isinstance(f, models.DateField) or isinstance(f, models.TimeField): diff --git a/tests/regressiontests/admin_changelist/models.py b/tests/regressiontests/admin_changelist/models.py index f030a781e9..858d6dfd45 100644 --- a/tests/regressiontests/admin_changelist/models.py +++ b/tests/regressiontests/admin_changelist/models.py @@ -5,5 +5,5 @@ class Parent(models.Model): name = models.CharField(max_length=128) class Child(models.Model): - parent = models.ForeignKey(Parent, editable=False) - name = models.CharField(max_length=30, blank=True) \ No newline at end of file + parent = models.ForeignKey(Parent, editable=False, null=True) + name = models.CharField(max_length=30, blank=True) diff --git a/tests/regressiontests/admin_changelist/tests.py b/tests/regressiontests/admin_changelist/tests.py index fca1b9e57c..c3f6186770 100644 --- a/tests/regressiontests/admin_changelist/tests.py +++ b/tests/regressiontests/admin_changelist/tests.py @@ -20,6 +20,26 @@ class ChangeListTests(TransactionTestCase): m.list_select_related, m.list_per_page, m.list_editable, m) self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}}) + def test_result_list_empty_changelist_value(self): + """ + Regression test for #14982: EMPTY_CHANGELIST_VALUE should be honored + for relationship fields + """ + new_child = Child.objects.create(name='name', parent=None) + request = MockRequest() + m = ChildAdmin(Child, admin.site) + cl = ChangeList(request, Child, m.list_display, m.list_display_links, + m.list_filter, m.date_hierarchy, m.search_fields, + m.list_select_related, m.list_per_page, m.list_editable, m) + cl.formset = None + template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') + context = Context({'cl': cl}) + table_output = template.render(context) + row_html = '