From 4e0ff351466fc2d74cc8d1d40ea78da2b3859d0d Mon Sep 17 00:00:00 2001 From: Julien Phalip Date: Sat, 27 Jul 2013 19:50:02 -0700 Subject: [PATCH] Fixed #11195 -- Added CSS classes to the changelist cells to allow style customizations. Thanks to akaihola, Ramiro Morales and vdboor for their work on the patch. --- .../contrib/admin/templatetags/admin_list.py | 9 ++++--- docs/releases/1.7.txt | 3 +++ tests/admin_changelist/tests.py | 6 ++--- tests/admin_views/tests.py | 26 +++++++++++++++---- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index 8596dfb825..6c3c3e8511 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -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: @@ -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: @@ -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) @@ -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] diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 3526b2bce7..eaf1385cf4 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -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-`` class in the + HTML to enable style customizations. + Backwards incompatible changes in 1.7 ===================================== diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 7f3f0d162e..fb72f60b7c 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -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 = 'name(None)' % link + row_html = 'name(None)' % link self.assertFalse(table_output.find(row_html) == -1, 'Failed to find expected row element: %s' % table_output) @@ -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 = 'nameParent object' % link + row_html = 'nameParent object' % link self.assertFalse(table_output.find(row_html) == -1, 'Failed to find expected row element: %s' % table_output) @@ -150,7 +150,7 @@ class ChangeListTests(TestCase): # make sure that list editable fields are rendered in divs correctly editable_name_field = '' - self.assertInHTML('%s' % editable_name_field, table_output, msg_prefix='Failed to find "name" list_editable field') + self.assertInHTML('%s' % editable_name_field, table_output, msg_prefix='Failed to find "name" list_editable field') def test_result_list_editable(self): """ diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 7decf6f471..80fdb90402 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -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 = """%s""" % (prefix, pk_final_url, escape(self.pk)) + should_contain = """%s""" % (prefix, pk_final_url, escape(self.pk)) self.assertContains(response, should_contain) def test_recentactions_link(self): @@ -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, '
\n\n
' % (story2.id, story1.id), html=True) - self.assertContains(response, '%d' % story1.id, 1) - self.assertContains(response, '%d' % story2.id, 1) + self.assertContains(response, '%d' % story1.id, 1) + self.assertContains(response, '%d' % 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 @@ -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, '
\n\n
' % (story2.id, story1.id), html=True) - self.assertContains(response, '%d' % (link1, story1.id), 1) - self.assertContains(response, '%d' % (link2, story2.id), 1) + self.assertContains(response, '%d' % (link1, story1.id), 1) + self.assertContains(response, '%d' % (link2, story2.id), 1) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) @@ -3877,6 +3877,22 @@ class CSSTest(TestCase): self.assertContains(response, '') + self.assertContains( + response, '') + self.assertContains( + response, '') + + try: import docutils except ImportError: