* Gives the `result_row_display` control over the `<tr>` element for each row in `IndexView` by shifting the `<tr>` out of `result_list.html` and into `result_row.html`

* `result_row_display` adds a `data-object_pk` attribute to each row, to make items easier to identify with JS
* Adds `get_extra_attrs_for_row()` method to `ModelAdmin`, to give developers a way of adding further attributes to the `<tr>` element
pull/3074/merge
Andy Babic 2016-10-09 13:53:39 +01:00 zatwierdzone przez Matt Westcott
rodzic 512bf8936d
commit 78f67f8fdb
9 zmienionych plików z 92 dodań i 10 usunięć

Wyświetl plik

@ -7,6 +7,7 @@ Changelog
* Added support of a custom `edit_handler` in site settings (Axel Haustant)
* Added `get_landing_page_template` getter method to `AbstractForm` (Gagaro)
* Added `Page.get_admin_display_title` method to override how the title is displayed in the admin (Henk-Jan van Hasselaar)
* Added support for specifying custom HTML attributes for table rows on ModelAdmin index pages (Andy Babic)
* Fix: `AbstractForm` now respects custom `get_template` methods on the page model (Gagaro)
* Fix: Use specific page model for the parent page in the explore index (Gagaro)
* Fix: Remove responsive styles in embed when there is no ratio available (Gagaro)

Wyświetl plik

@ -362,6 +362,50 @@ For example:
return qs.filter(managed_by=request.user)
.. _modeladmin_get_extra_attrs_for_row:
----------------------------------------------------
``ModelAdmin.get_extra_attrs_for_row()``
----------------------------------------------------
**Must return**: A dictionary
The `get_extra_attrs_for_row` method allows you to add html attributes to
the opening `<tr>` tag for each result, in addition to the `data-object_pk` and
`class` attributes already added by the `result_row_display` tag.
If you want to add additional CSS classes, simply provide those class names
as a string value using the `class` key, and the `odd`/`even` will be appended
to your custom class names when rendering.
For example, if you wanted to add some additional class names based on field
values, you could do something like:
.. code-block:: python
from decimal import Decimal
from django.db import models
from wagtail.contrib.modeladmin.options import ModelAdmin
class BankAccount(models.Model):
name = models.CharField(max_length=50)
account_number = models.CharField(max_length=50)
balance = models.DecimalField(max_digits=5, num_places=2)
class BankAccountAdmin(ModelAdmin):
list_display = ('name', 'account_number', 'balance')
def get_extra_attrs_for_row(self, obj, context):
if obj.balance < Decimal('0.00'):
classname = 'balance-negative'
else:
classname = 'balance-positive'
return {
'class': classname,
}
.. _modeladmin_get_extra_class_names_for_field_col:
----------------------------------------------------

Wyświetl plik

@ -17,6 +17,7 @@ Minor features
* Added support of a custom ``edit_handler`` for site settings. See :ref:`docs for the site settings module <edit_handlers_settings>`. (Axel Haustant)
* Added ``get_landing_page_template`` getter method to ``AbstractForm`` (Gagaro)
* Added ``Page.get_admin_display_title`` method to override how the title is displayed in the admin (Henk-Jan van Hasselaar)
* Added support for specifying custom HTML attributes for table rows on ModelAdmin index pages. See :ref:`modeladmin_get_extra_attrs_for_row` (Andy Babic)
Bug fixes

Wyświetl plik

@ -259,6 +259,14 @@ class ModelAdmin(WagtailRegisterable):
"""
return self.search_fields or ()
def get_extra_attrs_for_row(self, obj, context):
"""
Return a dictionary of HTML attributes to be added to the `<tr>`
element for the suppled `obj` when rendering the results table in
`index_view`. `data-object-pk` is already added by default.
"""
return {}
def get_extra_class_names_for_field_col(self, obj, field_name):
"""
Return a list of additional CSS class names to be added to the table

Wyświetl plik

@ -14,9 +14,7 @@
</thead>
<tbody>
{% for result in results %}
<tr class="{% cycle 'odd' 'even' %}">
{% result_row_display forloop.counter0 %}
</tr>
{% result_row_display forloop.counter0 %}
{% endfor %}
</tbody>
</table>

Wyświetl plik

@ -1,4 +1,6 @@
{% load modeladmin_tags %}
{% for item in result %}
{% result_row_value_display forloop.counter0 %}
{% endfor %}
<tr{{ row_attrs }}>
{% for item in result %}
{% result_row_value_display forloop.counter0 %}
{% endfor %}
</tr>

Wyświetl plik

@ -7,6 +7,7 @@ from django.contrib.admin.templatetags.admin_list import ResultList, result_head
from django.contrib.admin.utils import display_for_field, display_for_value, lookup_field
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.forms.utils import flatatt
from django.template import Library
from django.template.loader import get_template
from django.utils.encoding import force_text
@ -74,10 +75,8 @@ def items_for_result(view, result):
row_attrs_dict = modeladmin.get_extra_attrs_for_field_col(
field_name, result)
row_attrs_dict['class'] = ' ' . join(row_classes)
row_attrs = ''.join(
' %s="%s"' % (key, val) for key, val in row_attrs_dict.items())
row_attrs_safe = mark_safe(row_attrs)
yield format_html('<td{}>{}</td>', row_attrs_safe, result_repr)
row_attrs = flatatt(row_attrs_dict)
yield format_html('<td{}>{}</td>', row_attrs, result_repr)
def results(view, object_list):
@ -156,8 +155,17 @@ def admin_list_filter(view, spec):
def result_row_display(context, index):
obj = context['object_list'][index]
view = context['view']
row_attrs_dict = view.model_admin.get_extra_attrs_for_row(obj, context)
row_attrs_dict['data-object-pk'] = obj.pk
odd_or_even = 'odd' if (index % 2 == 0) else 'even'
if 'class' in row_attrs_dict:
row_attrs_dict['class'] += ' %s' % odd_or_even
else:
row_attrs_dict['class'] = odd_or_even
context.update({
'obj': obj,
'row_attrs': mark_safe(flatatt(row_attrs_dict)),
'action_buttons': view.get_buttons_for_obj(obj),
})
return context

Wyświetl plik

@ -28,6 +28,19 @@ class TestIndexView(TestCase, WagtailTestUtils):
# User has add permission
self.assertEqual(response.context['user_can_create'], True)
def test_tr_attributes(self):
response = self.get()
# Charlie & The Chocolate factory should be in the list with the
# `data-author_yob` and `data-object_pk` attributes added
self.assertContains(response, 'data-author-yob="1916"')
self.assertContains(response, 'data-object-pk="3"')
# There should be two odd rows and two even ones, and 'book' should be
# add to the `class` attribute for every one.
self.assertContains(response, 'class="book odd"', count=2)
self.assertContains(response, 'class="book even"', count=2)
def test_filter(self):
# Filter by author 1 (JRR Tolkien)
response = self.get(author__id__exact=1)

Wyświetl plik

@ -21,10 +21,17 @@ class BookModelAdmin(ModelAdmin):
menu_order = 300
list_display = ('title', 'author')
list_filter = ('author', )
ordering = ('title', )
search_fields = ('title', )
inspect_view_enabled = True
inspect_view_fields_exclude = ('title', )
def get_extra_attrs_for_row(self, obj, context):
return {
'data-author-yob': obj.author.date_of_birth.year,
'class': 'book',
}
class TokenModelAdmin(ModelAdmin):
model = Token