From 617812966796c6f99e5bc94fa2e367ce06d69fac Mon Sep 17 00:00:00 2001 From: Will Barton Date: Tue, 30 Jul 2024 09:38:31 -0400 Subject: [PATCH] Update for universal listing report This change updates the Wagtail Block Inventory report to be a universal listing, per the [changes in Wagtail 6.2](https://docs.wagtail.org/en/latest/releases/6.2.html#changes-to-report-views-with-the-new-universal-listings-ui). Because the way universal listing filters work doesn't play well with django-autocomplete-lite and Select2, I've removed that dependency. To make the block selection filters more human-friendly (and less likely to truncate before the actual block name), I've also shortened the block name in the filter to just the block name itself, not the full module path of the block. This does risk some potential duplicate blocks, but I suspect it should be okay. Finally, because of the switch to universal listings, rather than continue to support old-and-new style reports, I've removed support for Wagtail < 6.2. This will necessitate a major release. --- .github/workflows/test.yml | 18 ++++------- README.rst | 12 +++----- pyproject.toml | 7 +---- tox.ini | 9 +++--- wagtailinventory/tests/settings.py | 2 -- wagtailinventory/tests/test_views.py | 32 ------------------- wagtailinventory/views.py | 46 +++++++++------------------- wagtailinventory/wagtail_hooks.py | 11 +++---- 8 files changed, 34 insertions(+), 103 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 181986b..9255113 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,19 +31,13 @@ jobs: strategy: matrix: - python: ['3.8', '3.12'] - django: ['4.2'] - wagtail: ['5.2', '6.0', '6.1'] + python: ['3.12'] + django: ['4.2', '5.0'] + wagtail: ['6.2'] include: - - python: '3.12' - django: '5.0' - wagtail: '5.2' - - python: '3.12' - django: '5.0' - wagtail: '6.0' - - python: '3.12' - django: '5.0' - wagtail: '6.1' + - python: '3.8' + django: '4.2' + wagtail: '6.2' steps: - uses: actions/checkout@v4 diff --git a/README.rst b/README.rst index ffc5915..0c84ed3 100644 --- a/README.rst +++ b/README.rst @@ -18,17 +18,13 @@ Install the package using pip: $ pip install wagtail-inventory -This will also install `django-autocomplete-light `_. - -Add ``dal``, ``dal_select2``, and ``wagtailinventory`` as installed apps in your Django settings: +Add `wagtailinventory`` as an installed app in your Django settings: .. code-block:: python # in settings.py INSTALLED_APPS = ( ... - 'dal', - 'dal_select2', 'wagtailinventory', ... ) @@ -54,9 +50,9 @@ Compatibility This code has been tested for compatibility with: -* Python 3.8+ -* Django 3.2 (LTS), 4.2 (LTS), 5.0 -* Wagtail 3.0+, including 5.2 (LTS) and 6.0 +* Python 3.8, 3.12 +* Django 4.2 (LTS), 5.0 +* Wagtail 6.2 It should be compatible with all intermediate versions, as well. If you find that it is not, please `file an issue `_. diff --git a/pyproject.toml b/pyproject.toml index d380eac..bb6d4da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,18 +14,13 @@ authors = [ ] dependencies = [ "tqdm>=4.15.0,<5", - "wagtail>=5.2", - "django-autocomplete-light>=3.9", + "wagtail==6.2rc1", ] classifiers = [ "Framework :: Django", - "Framework :: Django :: 3.2", "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", "Framework :: Wagtail", - "Framework :: Wagtail :: 3", - "Framework :: Wagtail :: 4", - "Framework :: Wagtail :: 5", "Framework :: Wagtail :: 6", "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", "License :: Public Domain", diff --git a/tox.ini b/tox.ini index 90f1b16..46971c7 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ skipsdist=True envlist= lint, - python3.8-django{4.2}-wagtail{5.2,6.0,6.1} - python3.12-django{4.2,5.0}-wagtail{5.2,6.0,6.1} + python3.8-django{4.2}-wagtail{6.2} + python3.12-django{4.2,5.0}-wagtail{6.2} coverage [testenv] @@ -18,9 +18,7 @@ basepython= deps= django4.2: Django>=4.2,<4.3 django5.0: Django>=5.0,<5.1 - wagtail5.2: wagtail>=5.2,<6.0 - wagtail6.0: wagtail>=6.0,<6.1 - wagtail6.1: wagtail>=6.1,<6.2 + wagtail6.2: wagtail==6.2rc1 [testenv:lint] basepython=python3.12 @@ -47,6 +45,7 @@ commands= basepython=python3.12 deps= Django>=5.0,<5.1 + wagtail==6.2rc1 commands_pre= python {toxinidir}/testmanage.py makemigrations diff --git a/wagtailinventory/tests/settings.py b/wagtailinventory/tests/settings.py index a2ffd9a..4e796ea 100644 --- a/wagtailinventory/tests/settings.py +++ b/wagtailinventory/tests/settings.py @@ -54,8 +54,6 @@ ) + WAGTAIL_APPS + ( - "dal", - "dal_select2", "wagtailinventory", "wagtailinventory.tests.testapp", ) diff --git a/wagtailinventory/tests/test_views.py b/wagtailinventory/tests/test_views.py index afc3739..ede80d3 100644 --- a/wagtailinventory/tests/test_views.py +++ b/wagtailinventory/tests/test_views.py @@ -1,6 +1,5 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission -from django.core.management import call_command from django.test import TestCase from django.urls import reverse @@ -11,37 +10,6 @@ User = get_user_model() -class BlockAutocompleteViewTestCase(WagtailTestUtils, TestCase): - fixtures = ["test_blocks.json"] - - def setUp(self): - self.login() - - def test_get_list(self): - call_command("block_inventory", verbosity=0) - response = self.client.get( - reverse("wagtailinventory:block_autocomplete") - ) - - json_response = response.json() - self.assertIn("results", json_response) - - results = json_response["results"] - - # There are six unique block types in our test fixture - self.assertEqual(len(results), 6) - - # Make sure that one of the results matches our expected id/text - # pairing - self.assertIn( - { - "id": "wagtail.blocks.field_block.CharBlock", - "text": "wagtail.blocks.field_block.CharBlock", - }, - results, - ) - - class BlockInventoryReportViewTestCase(WagtailTestUtils, TestCase): fixtures = ["test_blocks.json"] diff --git a/wagtailinventory/views.py b/wagtailinventory/views.py index a407461..00d059e 100644 --- a/wagtailinventory/views.py +++ b/wagtailinventory/views.py @@ -1,53 +1,35 @@ -import wagtail from wagtail.admin.auth import permission_denied from wagtail.admin.filters import ContentTypeFilter, WagtailFilterSet from wagtail.admin.views.reports import PageReportView -from wagtail.models import Page +from wagtail.models import Page, get_page_content_types import django_filters -from dal import autocomplete from wagtailinventory.models import PageBlock -if wagtail.VERSION >= (6,): - from wagtail.models import get_page_content_types -else: # pragma: no cover - # For Wagtail < 6, use an older method to get the list of page types. - from wagtail.admin.views.reports.aging_pages import ( - get_content_types_for_filter, - ) - - def get_page_content_types(include_base_page_type=True): - return get_content_types_for_filter() - - -class BlockAutocompleteView(autocomplete.Select2ListView): - def get_list(self): - return ( - PageBlock.objects.distinct() - .order_by("block") - .values_list("block", flat=True) - ) +def get_block_choices(): + return [ + (page_block, page_block.rsplit(".", 1)[1]) + for page_block in PageBlock.objects.distinct() + .order_by("block") + .values_list("block", flat=True) + ] class BlockInventoryFilterSet(WagtailFilterSet): - include_page_blocks = django_filters.AllValuesMultipleFilter( + include_page_blocks = django_filters.MultipleChoiceFilter( field_name="page_blocks__block", label="Include Blocks", distinct=True, - widget=autocomplete.Select2Multiple( - url="wagtailinventory:block_autocomplete" - ), + choices=get_block_choices, ) - exclude_page_blocks = django_filters.AllValuesMultipleFilter( + exclude_page_blocks = django_filters.MultipleChoiceFilter( field_name="page_blocks__block", label="Exclude Blocks", distinct=True, exclude=True, - widget=autocomplete.Select2Multiple( - url="wagtailinventory:block_autocomplete" - ), + choices=get_block_choices, ) content_type = ContentTypeFilter( label="Page Type", @@ -60,9 +42,11 @@ class Meta: class BlockInventoryReportView(PageReportView): - title = "Block inventory" + page_title = "Block inventory" header_icon = "placeholder" filterset_class = BlockInventoryFilterSet + index_url_name = "wagtailinventory:block_inventory_report" + index_results_url_name = "wagtailinventory:block_inventory_report_results" @classmethod def check_permissions(cls, request): diff --git a/wagtailinventory/wagtail_hooks.py b/wagtailinventory/wagtail_hooks.py index d39f3c3..874bba9 100644 --- a/wagtailinventory/wagtail_hooks.py +++ b/wagtailinventory/wagtail_hooks.py @@ -9,10 +9,7 @@ delete_page_inventory, update_page_inventory, ) -from wagtailinventory.views import ( - BlockAutocompleteView, - BlockInventoryReportView, -) +from wagtailinventory.views import BlockInventoryReportView @hooks.register("after_create_page") @@ -61,9 +58,9 @@ def register_inventory_report_url(): name="block_inventory_report", ), path( - "block-autocomplete/", - BlockAutocompleteView.as_view(), - name="block_autocomplete", + "results/", + BlockInventoryReportView.as_view(results_only=True), + name="block_inventory_report_results", ), ]