mirror of https://github.com/django/django.git
Fixed #29953 -- Added CSS class to column headers in tabular inlines.
The class name is the same as one given to the fields in the change list.
This commit is contained in:
parent
acdd18dffc
commit
2e4776196d
|
@ -279,6 +279,7 @@ class InlineAdminFormSet:
|
||||||
continue
|
continue
|
||||||
if not self.has_change_permission or field_name in self.readonly_fields:
|
if not self.has_change_permission or field_name in self.readonly_fields:
|
||||||
yield {
|
yield {
|
||||||
|
'name': field_name,
|
||||||
'label': meta_labels.get(field_name) or label_for_field(field_name, self.opts.model, self.opts),
|
'label': meta_labels.get(field_name) or label_for_field(field_name, self.opts.model, self.opts),
|
||||||
'widget': {'is_hidden': False},
|
'widget': {'is_hidden': False},
|
||||||
'required': False,
|
'required': False,
|
||||||
|
@ -290,6 +291,7 @@ class InlineAdminFormSet:
|
||||||
if label is None:
|
if label is None:
|
||||||
label = label_for_field(field_name, self.opts.model, self.opts)
|
label = label_for_field(field_name, self.opts.model, self.opts)
|
||||||
yield {
|
yield {
|
||||||
|
'name': field_name,
|
||||||
'label': label,
|
'label': label,
|
||||||
'widget': form_field.widget,
|
'widget': form_field.widget,
|
||||||
'required': form_field.required,
|
'required': form_field.required,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<th class="original"></th>
|
<th class="original"></th>
|
||||||
{% for field in inline_admin_formset.fields %}
|
{% for field in inline_admin_formset.fields %}
|
||||||
{% if not field.widget.is_hidden %}
|
{% if not field.widget.is_hidden %}
|
||||||
<th{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
|
<th class="column-{{ field.name }}{% if field.required %} required{% endif %}">{{ field.label|capfirst }}
|
||||||
{% if field.help_text %} <img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}">{% endif %}
|
{% if field.help_text %} <img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}">{% endif %}
|
||||||
</th>
|
</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -44,7 +44,8 @@ Minor features
|
||||||
:mod:`django.contrib.admin`
|
:mod:`django.contrib.admin`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* Added a CSS class to the column headers of
|
||||||
|
:class:`~django.contrib.admin.TabularInline`.
|
||||||
|
|
||||||
:mod:`django.contrib.admindocs`
|
:mod:`django.contrib.admindocs`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -152,6 +152,7 @@ class Poll(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class Question(models.Model):
|
class Question(models.Model):
|
||||||
|
text = models.CharField(max_length=40)
|
||||||
poll = models.ForeignKey(Poll, models.CASCADE)
|
poll = models.ForeignKey(Poll, models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,13 +85,27 @@ class TestInline(TestDataMixin, TestCase):
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1)
|
self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1)
|
||||||
|
|
||||||
|
def test_tabular_inline_column_css_class(self):
|
||||||
|
"""
|
||||||
|
Field names are included in the context to output a field-specific
|
||||||
|
CSS class name in the column headers.
|
||||||
|
"""
|
||||||
|
response = self.client.get(reverse('admin:admin_inlines_poll_add'))
|
||||||
|
text_field, call_me_field = list(response.context['inline_admin_formset'].fields())
|
||||||
|
# Editable field.
|
||||||
|
self.assertEqual(text_field['name'], 'text')
|
||||||
|
self.assertContains(response, '<th class="column-text required">')
|
||||||
|
# Read-only field.
|
||||||
|
self.assertEqual(call_me_field['name'], 'call_me')
|
||||||
|
self.assertContains(response, '<th class="column-call_me">')
|
||||||
|
|
||||||
def test_custom_form_tabular_inline_label(self):
|
def test_custom_form_tabular_inline_label(self):
|
||||||
"""
|
"""
|
||||||
A model form with a form field specified (TitleForm.title1) should have
|
A model form with a form field specified (TitleForm.title1) should have
|
||||||
its label rendered in the tabular inline.
|
its label rendered in the tabular inline.
|
||||||
"""
|
"""
|
||||||
response = self.client.get(reverse('admin:admin_inlines_titlecollection_add'))
|
response = self.client.get(reverse('admin:admin_inlines_titlecollection_add'))
|
||||||
self.assertContains(response, '<th class="required">Title1</th>', html=True)
|
self.assertContains(response, '<th class="column-title1 required">Title1</th>', html=True)
|
||||||
|
|
||||||
def test_custom_form_tabular_inline_overridden_label(self):
|
def test_custom_form_tabular_inline_overridden_label(self):
|
||||||
"""
|
"""
|
||||||
|
@ -101,7 +115,7 @@ class TestInline(TestDataMixin, TestCase):
|
||||||
response = self.client.get(reverse('admin:admin_inlines_someparentmodel_add'))
|
response = self.client.get(reverse('admin:admin_inlines_someparentmodel_add'))
|
||||||
field = list(response.context['inline_admin_formset'].fields())[0]
|
field = list(response.context['inline_admin_formset'].fields())[0]
|
||||||
self.assertEqual(field['label'], 'new label')
|
self.assertEqual(field['label'], 'new label')
|
||||||
self.assertContains(response, '<th class="required">New label</th>', html=True)
|
self.assertContains(response, '<th class="column-name required">New label</th>', html=True)
|
||||||
|
|
||||||
def test_tabular_non_field_errors(self):
|
def test_tabular_non_field_errors(self):
|
||||||
"""
|
"""
|
||||||
|
@ -710,7 +724,7 @@ class TestInlinePermissions(TestCase):
|
||||||
html=True
|
html=True
|
||||||
)
|
)
|
||||||
# TabularInline
|
# TabularInline
|
||||||
self.assertContains(response, '<th class="required">Dummy</th>', html=True)
|
self.assertContains(response, '<th class="column-dummy required">Dummy</th>', html=True)
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
response,
|
response,
|
||||||
'<input type="number" name="inner2_set-2-0-dummy" value="%s" '
|
'<input type="number" name="inner2_set-2-0-dummy" value="%s" '
|
||||||
|
@ -781,7 +795,7 @@ class TestInlinePermissions(TestCase):
|
||||||
)
|
)
|
||||||
self.assertContains(response, 'id="id_inner2_set-0-DELETE"')
|
self.assertContains(response, 'id="id_inner2_set-0-DELETE"')
|
||||||
# TabularInline
|
# TabularInline
|
||||||
self.assertContains(response, '<th class="required">Dummy</th>', html=True)
|
self.assertContains(response, '<th class="column-dummy required">Dummy</th>', html=True)
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
response,
|
response,
|
||||||
'<input type="number" name="inner2_set-2-0-dummy" value="%s" '
|
'<input type="number" name="inner2_set-2-0-dummy" value="%s" '
|
||||||
|
|
Loading…
Reference in New Issue