kopia lustrzana https://github.com/wagtail/wagtail
Move SnippetViewSet.list_diplay definition to ModelViewSet
rodzic
71aa1d2a3e
commit
cd222898fd
|
@ -48,7 +48,7 @@ There are a few attributes of `ModelAdmin` that need to be renamed/adjusted for
|
|||
| ---------------------- | -------------------------- | ----- |
|
||||
| `add_to_admin_menu` | {attr}`~SnippetViewSet.add_to_admin_menu` | Same attribute name, but the value defaults to `False` instead of `True`. Set to `True` to add a top-level menu item for the model. |
|
||||
| `menu_icon` | {attr}`~SnippetViewSet.icon` | Same value, but different attribute name, as the icon is used throughout the admin and not just in the menu. |
|
||||
| `list_display` | {attr}`~SnippetViewSet.list_display` | Same attribute name, but the list/tuple of strings must refer to existing attributes or methods on the model, not the `SnippetViewSet` class. If you have specified a string that refers to an attribute or method on the `ModelAdmin` class, you need to move it to the model. In addition, `list_display` now also supports instances of the `wagtail.admin.ui.tables.Column` component class. |
|
||||
| `list_display` | {attr}`~wagtail.admin.viewsets.model.ModelViewSet.list_display` | Same attribute name, but the list/tuple of strings must refer to existing attributes or methods on the model, not the `SnippetViewSet` class. If you have specified a string that refers to an attribute or method on the `ModelAdmin` class, you need to move it to the model. In addition, `list_display` now also supports instances of the `wagtail.admin.ui.tables.Column` component class. |
|
||||
| `list_filter` | {attr}`~SnippetViewSet.list_filter` | Same attribute name and value, but filtering is built on top of the django-filter package under the hood, which behaves differently to ModelAdmin's filters. See documentation for `SnippetViewSet.list_filter` and {attr}`~SnippetViewSet.filterset_class` for more details. |
|
||||
| `form_fields_exclude` | {attr}`~wagtail.admin.viewsets.model.ModelViewSet.exclude_form_fields` | Same value, but different attribute name to better align with `ModelViewSet`. |
|
||||
| - | {attr}`~SnippetViewSet.template_prefix` | New attribute. Set to the name of a template directory to override the `"wagtailsnippets/snippets/"` default. If set to `"modeladmin/"`, the template directory structure will be equal to what ModelAdmin uses. Make sure any custom templates are placed in the correct directory according to this prefix. See [](wagtailsnippets_templates) for more details. |
|
||||
|
|
|
@ -80,6 +80,7 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
|
|||
:attr:`~django.db.models.Options.verbose_name_plural`.
|
||||
|
||||
.. autoattribute:: add_to_reference_index
|
||||
.. autoattribute:: list_display
|
||||
.. autoattribute:: index_view_class
|
||||
.. autoattribute:: add_view_class
|
||||
.. autoattribute:: edit_view_class
|
||||
|
@ -145,7 +146,6 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
|
|||
.. autoclass:: wagtail.snippets.views.snippets.SnippetViewSet
|
||||
|
||||
.. autoattribute:: model
|
||||
.. autoattribute:: list_display
|
||||
.. autoattribute:: list_export
|
||||
.. autoattribute:: list_filter
|
||||
.. autoattribute:: filterset_class
|
||||
|
|
|
@ -86,7 +86,7 @@ Similar URL customisations are also possible for the snippet chooser views throu
|
|||
|
||||
## Listing view
|
||||
|
||||
The {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.list_display` attribute can be set to specify the columns shown on the listing view. To customise the number of items to be displayed per page, you can set the {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.list_per_page` attribute (or {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.chooser_per_page` for the chooser listing).
|
||||
The {attr}`~wagtail.admin.viewsets.model.ModelViewSet.list_display` attribute can be set to specify the columns shown on the listing view. To customise the number of items to be displayed per page, you can set the {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.list_per_page` attribute (or {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.chooser_per_page` for the chooser listing).
|
||||
|
||||
To customise the base queryset for the listing view, you could override the {meth}`~wagtail.snippets.views.snippets.SnippetViewSet.get_queryset` method. Additionally, the {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.ordering` attribute can be used to specify the default ordering of the listing view.
|
||||
|
||||
|
|
|
@ -115,3 +115,40 @@ class TestTemplateConfiguration(WagtailTestUtils, TestCase):
|
|||
self.assertContains(
|
||||
response, "<p>Some extra custom content</p>", html=True
|
||||
)
|
||||
|
||||
|
||||
class TestCustomColumns(WagtailTestUtils, TestCase):
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
FeatureCompleteToy.objects.create(name="Racecar")
|
||||
FeatureCompleteToy.objects.create(name="level")
|
||||
FeatureCompleteToy.objects.create(name="Lotso")
|
||||
|
||||
def test_list_display(self):
|
||||
index_url = reverse("feature_complete_toy:index")
|
||||
response = self.client.get(index_url)
|
||||
# "name" column
|
||||
self.assertContains(response, "Racecar")
|
||||
self.assertContains(response, "level")
|
||||
self.assertContains(response, "Lotso")
|
||||
# BooleanColumn("is_cool")
|
||||
soup = self.get_soup(response.content)
|
||||
|
||||
help = soup.select_one("td:has(svg.icon-help)")
|
||||
self.assertIsNotNone(help)
|
||||
self.assertEqual(help.text.strip(), "None")
|
||||
|
||||
success = soup.select_one("td:has(svg.icon-success.w-text-positive-100)")
|
||||
self.assertIsNotNone(success)
|
||||
self.assertEqual(success.text.strip(), "True")
|
||||
|
||||
error = soup.select_one("td:has(svg.icon-error.w-text-critical-100)")
|
||||
self.assertIsNotNone(error)
|
||||
self.assertEqual(error.text.strip(), "False")
|
||||
|
||||
updated_at = soup.select("th a")[-1]
|
||||
self.assertEqual(updated_at.text.strip(), "Updated")
|
||||
self.assertEqual(updated_at["href"], f"{index_url}?ordering=_updated_at")
|
||||
|
|
|
@ -76,6 +76,7 @@ class ModelViewSet(ViewSet):
|
|||
"add_url_name": self.get_url_name("add"),
|
||||
"edit_url_name": self.get_url_name("edit"),
|
||||
"header_icon": self.icon,
|
||||
"list_display": self.list_display,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
|
@ -239,6 +240,32 @@ class ModelViewSet(ViewSet):
|
|||
fallback=self.delete_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def list_display(self):
|
||||
"""
|
||||
A list or tuple, where each item is either:
|
||||
|
||||
- The name of a field on the model;
|
||||
- The name of a callable or property on the model that accepts a single
|
||||
parameter for the model instance; or
|
||||
- An instance of the ``wagtail.admin.ui.tables.Column`` class.
|
||||
|
||||
If the name refers to a database field, the ability to sort the listing
|
||||
by the database column will be offerred and the field's verbose name
|
||||
will be used as the column header.
|
||||
|
||||
If the name refers to a callable or property, an ``admin_order_field``
|
||||
attribute can be defined on it to point to the database column for
|
||||
sorting. A ``short_description`` attribute can also be defined on the
|
||||
callable or property to be used as the column header.
|
||||
|
||||
This list will be passed to the ``list_display`` attribute of the index
|
||||
view. If left unset, the ``list_display`` attribute of the index view
|
||||
will be used instead, which by default is defined as
|
||||
``["__str__", wagtail.admin.ui.tables.UpdatedAtColumn()]``.
|
||||
"""
|
||||
return self.index_view_class.list_display
|
||||
|
||||
@cached_property
|
||||
def menu_label(self):
|
||||
return self.model_opts.verbose_name_plural.title()
|
||||
|
|
|
@ -624,21 +624,6 @@ class SnippetViewSet(ModelViewSet):
|
|||
#: A subclass of ``wagtail.admin.filters.WagtailFilterSet``, which is a subclass of `django_filters.FilterSet <https://django-filter.readthedocs.io/en/stable/ref/filterset.html>`_. This will be passed to the ``filterset_class`` attribute of the index view.
|
||||
filterset_class = None
|
||||
|
||||
#: A list or tuple, where each item is either:
|
||||
#:
|
||||
#: - The name of a field on the model;
|
||||
#: - The name of a callable or property on the model that accepts a single parameter for the model instance; or
|
||||
#: - An instance of the ``wagtail.admin.ui.tables.Column`` class.
|
||||
#:
|
||||
#: If the name refers to a database field, the ability to sort the listing by the database column will be offerred and the field's verbose name will be used as the column header.
|
||||
#:
|
||||
#: If the name refers to a callable or property, a ``admin_order_field`` attribute can be defined on it to point to the database column for sorting.
|
||||
#: A ``short_description`` attribute can also be defined on the callable or property to be used as the column header.
|
||||
#:
|
||||
#: This list will be passed to the ``list_display`` attribute of the index view.
|
||||
#: If left unset, the ``list_display`` attribute of the index view will be used instead, which by default is defined as ``["__str__", wagtail.admin.ui.tables.UpdatedAtColumn()]``.
|
||||
list_display = None
|
||||
|
||||
#: A list or tuple, where each item is the name of model fields of type ``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``, ``IntegerField`` or ``ForeignKey``.
|
||||
#: Alternatively, it can also be a dictionary that maps a field name to a list of lookup expressions.
|
||||
#: This will be passed as django-filter's ``FilterSet.Meta.fields`` attribute. See `its documentation <https://django-filter.readthedocs.io/en/stable/guide/usage.html#generating-filters-with-meta-fields>`_ for more details.
|
||||
|
@ -799,11 +784,6 @@ class SnippetViewSet(ModelViewSet):
|
|||
self, "menu_item_is_registered", bool(self.menu_hook)
|
||||
)
|
||||
|
||||
if not self.list_display:
|
||||
self.list_display = self.index_view_class.list_display.copy()
|
||||
if self.draftstate_enabled:
|
||||
self.list_display += [LiveStatusTagColumn()]
|
||||
|
||||
# This edit handler has been bound to the model and is used for the views.
|
||||
self._edit_handler = self.get_edit_handler()
|
||||
|
||||
|
@ -848,7 +828,6 @@ class SnippetViewSet(ModelViewSet):
|
|||
index_url_name=self.get_url_name("list"),
|
||||
index_results_url_name=self.get_url_name("list_results"),
|
||||
delete_url_name=self.get_url_name("delete"),
|
||||
list_display=self.list_display,
|
||||
list_filter=self.list_filter,
|
||||
list_export=self.list_export,
|
||||
export_filename=self.get_export_filename(),
|
||||
|
@ -1104,6 +1083,13 @@ class SnippetViewSet(ModelViewSet):
|
|||
per_page=self.chooser_per_page,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def list_display(self):
|
||||
list_display = super().list_display.copy()
|
||||
if self.draftstate_enabled:
|
||||
list_display.append(LiveStatusTagColumn())
|
||||
return list_display
|
||||
|
||||
@cached_property
|
||||
def icon(self):
|
||||
return self.get_icon()
|
||||
|
|
|
@ -2140,3 +2140,10 @@ class GenericSnippetNoFieldIndexPage(GenericSnippetPage):
|
|||
# Models to be registered with a ModelViewSet
|
||||
class FeatureCompleteToy(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def is_cool(self):
|
||||
if self.name == self.name[::-1]:
|
||||
return True
|
||||
if (lowered := self.name.lower()) == lowered[::-1]:
|
||||
return None
|
||||
return False
|
||||
|
|
|
@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy
|
|||
|
||||
from wagtail.admin import messages
|
||||
from wagtail.admin.auth import user_passes_test
|
||||
from wagtail.admin.ui.tables import BooleanColumn, UpdatedAtColumn
|
||||
from wagtail.admin.views.generic import DeleteView, EditView, IndexView
|
||||
from wagtail.admin.viewsets.base import ViewSet, ViewSetGroup
|
||||
from wagtail.admin.viewsets.model import ModelViewSet, ModelViewSetGroup
|
||||
|
@ -203,3 +204,4 @@ class FeatureCompleteToyViewSet(ModelViewSet):
|
|||
add_to_admin_menu = True
|
||||
template_prefix = "customprefix/"
|
||||
index_template_name = "tests/fctoy_index.html"
|
||||
list_display = ["name", BooleanColumn("is_cool"), UpdatedAtColumn()]
|
||||
|
|
Ładowanie…
Reference in New Issue