Loading django/contrib/admin/templatetags/admin_list.py +5 −4 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ def items_for_result(cl, result, form): first = True pk = cl.lookup_opts.pk.attname for field_name in cl.list_display: row_class = '' row_classes = ['field-%s' % field_name] try: f, attr, value = lookup_field(field_name, result, cl.model_admin) except ObjectDoesNotExist: Loading @@ -188,7 +188,7 @@ def items_for_result(cl, result, form): else: if f is None: if field_name == 'action_checkbox': row_class = mark_safe(' class="action-checkbox"') row_classes = ['action-checkbox'] allow_tags = getattr(attr, 'allow_tags', False) boolean = getattr(attr, 'boolean', False) if boolean: Loading @@ -199,7 +199,7 @@ def items_for_result(cl, result, form): if allow_tags: result_repr = mark_safe(result_repr) if isinstance(value, (datetime.date, datetime.time)): row_class = mark_safe(' class="nowrap"') row_classes.append('nowrap') else: if isinstance(f.rel, models.ManyToOneRel): field_val = getattr(result, f.name) Loading @@ -210,9 +210,10 @@ def items_for_result(cl, result, form): else: result_repr = display_for_field(value, f) if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): row_class = mark_safe(' class="nowrap"') row_classes.append('nowrap') if force_text(result_repr) == '': result_repr = mark_safe(' ') row_class = mark_safe(' class="%s"' % ' '.join(row_classes)) # If list_display_links not defined, add the link tag to the first field if (first and not cl.list_display_links) or field_name in cl.list_display_links: table_tag = {True:'th', False:'td'}[first] Loading docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ Minor features * Buttons in :mod:`django.contrib.admin` now use the ``border-radius`` CSS property for rounded corners rather than GIF background images. * The admin changelist cells now have a ``field-<field_name>`` class in the HTML to enable style customizations. Backwards incompatible changes in 1.7 ===================================== Loading tests/admin_changelist/tests.py +3 −3 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ class ChangeListTests(TestCase): context = Context({'cl': cl}) table_output = template.render(context) link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) row_html = '<tbody><tr class="row1"><th><a href="%s">name</a></th><td class="nowrap">(None)</td></tr></tbody>' % link row_html = '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th><td class="field-parent nowrap">(None)</td></tr></tbody>' % link self.assertFalse(table_output.find(row_html) == -1, 'Failed to find expected row element: %s' % table_output) Loading @@ -114,7 +114,7 @@ class ChangeListTests(TestCase): context = Context({'cl': cl}) table_output = template.render(context) link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) row_html = '<tbody><tr class="row1"><th><a href="%s">name</a></th><td class="nowrap">Parent object</td></tr></tbody>' % link row_html = '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th><td class="field-parent nowrap">Parent object</td></tr></tbody>' % link self.assertFalse(table_output.find(row_html) == -1, 'Failed to find expected row element: %s' % table_output) Loading Loading @@ -150,7 +150,7 @@ class ChangeListTests(TestCase): # make sure that list editable fields are rendered in divs correctly editable_name_field = '<input name="form-0-name" value="name" class="vTextField" maxlength="30" type="text" id="id_form-0-name" />' self.assertInHTML('<td>%s</td>' % editable_name_field, table_output, msg_prefix='Failed to find "name" list_editable field') self.assertInHTML('<td class="field-name">%s</td>' % editable_name_field, table_output, msg_prefix='Failed to find "name" list_editable field') def test_result_list_editable(self): """ Loading tests/admin_views/tests.py +21 −5 Original line number Diff line number Diff line Loading @@ -1496,7 +1496,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): response = self.client.get(prefix) # this URL now comes through reverse(), thus url quoting and iri_to_uri encoding pk_final_url = escape(iri_to_uri(urlquote(quote(self.pk)))) should_contain = """<th><a href="%s%s/">%s</a></th>""" % (prefix, pk_final_url, escape(self.pk)) should_contain = """<th class="field-__str__"><a href="%s%s/">%s</a></th>""" % (prefix, pk_final_url, escape(self.pk)) self.assertContains(response, should_contain) def test_recentactions_link(self): Loading Loading @@ -2151,8 +2151,8 @@ class AdminViewListEditable(TestCase): self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table. self.assertContains(response, 'id="id_form-1-id"', 1) self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True) self.assertContains(response, '<td>%d</td>' % story1.id, 1) self.assertContains(response, '<td>%d</td>' % story2.id, 1) self.assertContains(response, '<td class="field-id">%d</td>' % story1.id, 1) self.assertContains(response, '<td class="field-id">%d</td>' % story2.id, 1) def test_pk_hidden_fields_with_list_display_links(self): """ Similarly as test_pk_hidden_fields, but when the hidden pk fields are Loading @@ -2167,8 +2167,8 @@ class AdminViewListEditable(TestCase): self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table. self.assertContains(response, 'id="id_form-1-id"', 1) self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True) self.assertContains(response, '<th><a href="%s">%d</a></th>' % (link1, story1.id), 1) self.assertContains(response, '<th><a href="%s">%d</a></th>' % (link2, story2.id), 1) self.assertContains(response, '<th class="field-id"><a href="%s">%d</a></th>' % (link1, story1.id), 1) self.assertContains(response, '<th class="field-id"><a href="%s">%d</a></th>' % (link2, story2.id), 1) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) Loading Loading @@ -3877,6 +3877,22 @@ class CSSTest(TestCase): self.assertContains(response, '<body class="app-admin_views model-section ') def test_changelist_field_classes(self): """ Cells of the change list table should contain the field name in their class attribute Refs #11195. """ Podcast.objects.create(name="Django Dose", release_date=datetime.date.today()) response = self.client.get('/test_admin/admin/admin_views/podcast/') self.assertContains( response, '<th class="field-name">') self.assertContains( response, '<td class="field-release_date nowrap">') self.assertContains( response, '<td class="action-checkbox">') try: import docutils except ImportError: Loading Loading
django/contrib/admin/templatetags/admin_list.py +5 −4 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ def items_for_result(cl, result, form): first = True pk = cl.lookup_opts.pk.attname for field_name in cl.list_display: row_class = '' row_classes = ['field-%s' % field_name] try: f, attr, value = lookup_field(field_name, result, cl.model_admin) except ObjectDoesNotExist: Loading @@ -188,7 +188,7 @@ def items_for_result(cl, result, form): else: if f is None: if field_name == 'action_checkbox': row_class = mark_safe(' class="action-checkbox"') row_classes = ['action-checkbox'] allow_tags = getattr(attr, 'allow_tags', False) boolean = getattr(attr, 'boolean', False) if boolean: Loading @@ -199,7 +199,7 @@ def items_for_result(cl, result, form): if allow_tags: result_repr = mark_safe(result_repr) if isinstance(value, (datetime.date, datetime.time)): row_class = mark_safe(' class="nowrap"') row_classes.append('nowrap') else: if isinstance(f.rel, models.ManyToOneRel): field_val = getattr(result, f.name) Loading @@ -210,9 +210,10 @@ def items_for_result(cl, result, form): else: result_repr = display_for_field(value, f) if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): row_class = mark_safe(' class="nowrap"') row_classes.append('nowrap') if force_text(result_repr) == '': result_repr = mark_safe(' ') row_class = mark_safe(' class="%s"' % ' '.join(row_classes)) # If list_display_links not defined, add the link tag to the first field if (first and not cl.list_display_links) or field_name in cl.list_display_links: table_tag = {True:'th', False:'td'}[first] Loading
docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,9 @@ Minor features * Buttons in :mod:`django.contrib.admin` now use the ``border-radius`` CSS property for rounded corners rather than GIF background images. * The admin changelist cells now have a ``field-<field_name>`` class in the HTML to enable style customizations. Backwards incompatible changes in 1.7 ===================================== Loading
tests/admin_changelist/tests.py +3 −3 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ class ChangeListTests(TestCase): context = Context({'cl': cl}) table_output = template.render(context) link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) row_html = '<tbody><tr class="row1"><th><a href="%s">name</a></th><td class="nowrap">(None)</td></tr></tbody>' % link row_html = '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th><td class="field-parent nowrap">(None)</td></tr></tbody>' % link self.assertFalse(table_output.find(row_html) == -1, 'Failed to find expected row element: %s' % table_output) Loading @@ -114,7 +114,7 @@ class ChangeListTests(TestCase): context = Context({'cl': cl}) table_output = template.render(context) link = reverse('admin:admin_changelist_child_change', args=(new_child.id,)) row_html = '<tbody><tr class="row1"><th><a href="%s">name</a></th><td class="nowrap">Parent object</td></tr></tbody>' % link row_html = '<tbody><tr class="row1"><th class="field-name"><a href="%s">name</a></th><td class="field-parent nowrap">Parent object</td></tr></tbody>' % link self.assertFalse(table_output.find(row_html) == -1, 'Failed to find expected row element: %s' % table_output) Loading Loading @@ -150,7 +150,7 @@ class ChangeListTests(TestCase): # make sure that list editable fields are rendered in divs correctly editable_name_field = '<input name="form-0-name" value="name" class="vTextField" maxlength="30" type="text" id="id_form-0-name" />' self.assertInHTML('<td>%s</td>' % editable_name_field, table_output, msg_prefix='Failed to find "name" list_editable field') self.assertInHTML('<td class="field-name">%s</td>' % editable_name_field, table_output, msg_prefix='Failed to find "name" list_editable field') def test_result_list_editable(self): """ Loading
tests/admin_views/tests.py +21 −5 Original line number Diff line number Diff line Loading @@ -1496,7 +1496,7 @@ class AdminViewStringPrimaryKeyTest(TestCase): response = self.client.get(prefix) # this URL now comes through reverse(), thus url quoting and iri_to_uri encoding pk_final_url = escape(iri_to_uri(urlquote(quote(self.pk)))) should_contain = """<th><a href="%s%s/">%s</a></th>""" % (prefix, pk_final_url, escape(self.pk)) should_contain = """<th class="field-__str__"><a href="%s%s/">%s</a></th>""" % (prefix, pk_final_url, escape(self.pk)) self.assertContains(response, should_contain) def test_recentactions_link(self): Loading Loading @@ -2151,8 +2151,8 @@ class AdminViewListEditable(TestCase): self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table. self.assertContains(response, 'id="id_form-1-id"', 1) self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True) self.assertContains(response, '<td>%d</td>' % story1.id, 1) self.assertContains(response, '<td>%d</td>' % story2.id, 1) self.assertContains(response, '<td class="field-id">%d</td>' % story1.id, 1) self.assertContains(response, '<td class="field-id">%d</td>' % story2.id, 1) def test_pk_hidden_fields_with_list_display_links(self): """ Similarly as test_pk_hidden_fields, but when the hidden pk fields are Loading @@ -2167,8 +2167,8 @@ class AdminViewListEditable(TestCase): self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table. self.assertContains(response, 'id="id_form-1-id"', 1) self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True) self.assertContains(response, '<th><a href="%s">%d</a></th>' % (link1, story1.id), 1) self.assertContains(response, '<th><a href="%s">%d</a></th>' % (link2, story2.id), 1) self.assertContains(response, '<th class="field-id"><a href="%s">%d</a></th>' % (link1, story1.id), 1) self.assertContains(response, '<th class="field-id"><a href="%s">%d</a></th>' % (link2, story2.id), 1) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) Loading Loading @@ -3877,6 +3877,22 @@ class CSSTest(TestCase): self.assertContains(response, '<body class="app-admin_views model-section ') def test_changelist_field_classes(self): """ Cells of the change list table should contain the field name in their class attribute Refs #11195. """ Podcast.objects.create(name="Django Dose", release_date=datetime.date.today()) response = self.client.get('/test_admin/admin/admin_views/podcast/') self.assertContains( response, '<th class="field-name">') self.assertContains( response, '<td class="field-release_date nowrap">') self.assertContains( response, '<td class="action-checkbox">') try: import docutils except ImportError: Loading