From 0550b03dadc504ba3764db30f94607b4a56d36cf Mon Sep 17 00:00:00 2001 From: Sage Abdullah <sage.abdullah@torchbox.com> Date: Mon, 10 Jul 2023 10:20:04 +0100 Subject: [PATCH] Allow customising the spreadsheet file name via SnippetViewSet.export_filename --- docs/reference/viewsets.md | 1 + docs/topics/snippets/customising.md | 2 +- wagtail/admin/views/mixins.py | 4 +++- wagtail/snippets/tests/test_viewset.py | 10 ++++++++++ wagtail/snippets/views/snippets.py | 8 ++++++++ wagtail/test/testapp/wagtail_hooks.py | 1 + 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/reference/viewsets.md b/docs/reference/viewsets.md index 6a19124322..73cb301828 100644 --- a/docs/reference/viewsets.md +++ b/docs/reference/viewsets.md @@ -94,6 +94,7 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit .. autoattribute:: search_backend_name .. autoattribute:: list_per_page .. autoattribute:: chooser_per_page + .. autoattribute:: export_filename .. autoattribute:: ordering .. autoattribute:: admin_url_namespace .. autoattribute:: base_url_path diff --git a/docs/topics/snippets/customising.md b/docs/topics/snippets/customising.md index fba810db33..7d326fba22 100644 --- a/docs/topics/snippets/customising.md +++ b/docs/topics/snippets/customising.md @@ -93,7 +93,7 @@ You can add the ability to filter the listing view by defining a {attr}`~wagtail If you would like to make further customisations to the filtering mechanism, you can also use a custom `wagtail.admin.filters.WagtailFilterSet` subclass by overriding the {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.filterset_class` attribute. The `list_filter` attribute is ignored if `filterset_class` is set. For more details, refer to [django-filter's documentation](https://django-filter.readthedocs.io/en/stable/guide/usage.html#the-filter). -You can add the ability to export the listing view to a spreadsheet by setting the {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.list_export` attribute to specify the columns to be exported. +You can add the ability to export the listing view to a spreadsheet by setting the {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.list_export` attribute to specify the columns to be exported. The {attr}`~wagtail.snippets.views.snippets.SnippetViewSet.export_filename` attribute can be used to customise the file name of the exported spreadsheet. ```{versionadded} 5.1 The ability to export the listing view was added. diff --git a/wagtail/admin/views/mixins.py b/wagtail/admin/views/mixins.py index 6108550198..963c84b540 100644 --- a/wagtail/admin/views/mixins.py +++ b/wagtail/admin/views/mixins.py @@ -154,6 +154,8 @@ class SpreadsheetExportMixin: export_buttons_template_name = "wagtailadmin/shared/export_buttons.html" + export_filename = "spreadsheet-export" + def setup(self, request, *args, **kwargs): super().setup(request, *args, **kwargs) self.is_export = request.GET.get("export") in self.FORMATS @@ -165,7 +167,7 @@ class SpreadsheetExportMixin: def get_filename(self): """Gets the base filename for the exported spreadsheet, without extensions""" - return "spreadsheet-export" + return self.export_filename def to_row_dict(self, item): """Returns an OrderedDict (in the order given by list_export) of the exportable information for a model instance""" diff --git a/wagtail/snippets/tests/test_viewset.py b/wagtail/snippets/tests/test_viewset.py index 60448a1f7c..0a786609a1 100644 --- a/wagtail/snippets/tests/test_viewset.py +++ b/wagtail/snippets/tests/test_viewset.py @@ -707,6 +707,11 @@ class TestListExport(BaseSnippetViewSetTests): response = self.client.get(self.get_url("list"), {"export": "csv"}) self.assertEqual(response.status_code, 200) + self.assertEqual( + response.get("Content-Disposition"), + 'attachment; filename="all-fullfeatured-snippets.csv"', + ) + data_lines = response.getvalue().decode().split("\n") self.assertEqual( data_lines[0], @@ -725,6 +730,11 @@ class TestListExport(BaseSnippetViewSetTests): response = self.client.get(self.get_url("list"), {"export": "xlsx"}) self.assertEqual(response.status_code, 200) + self.assertEqual( + response.get("Content-Disposition"), + 'attachment; filename="all-fullfeatured-snippets.xlsx"', + ) + workbook_data = response.getvalue() worksheet = load_workbook(filename=BytesIO(workbook_data)).active cell_array = [[cell.value for cell in row] for row in worksheet.rows] diff --git a/wagtail/snippets/views/snippets.py b/wagtail/snippets/views/snippets.py index 6094b2aa46..4bbaff8c3a 100644 --- a/wagtail/snippets/views/snippets.py +++ b/wagtail/snippets/views/snippets.py @@ -672,6 +672,9 @@ class SnippetViewSet(ModelViewSet): #: A list or tuple, where each item is the name of a field, an attribute, or a single-argument callable on the model. list_export = [] + #: The base file name for the exported listing, without extensions. If unset, the model's :attr:`~django.db.models.Options.db_table` will be used instead. + export_filename = None + #: The number of items to display per page in the index view. Defaults to 20. list_per_page = 20 @@ -868,6 +871,7 @@ class SnippetViewSet(ModelViewSet): list_display=self.list_display, list_filter=self.list_filter, list_export=self.list_export, + export_filename=self.get_export_filename(), paginate_by=self.list_per_page, default_ordering=self.ordering, search_fields=self.search_fields, @@ -891,6 +895,7 @@ class SnippetViewSet(ModelViewSet): list_display=self.list_display, list_filter=self.list_filter, list_export=self.list_export, + export_filename=self.get_export_filename(), paginate_by=self.list_per_page, default_ordering=self.ordering, search_fields=self.search_fields, @@ -1238,6 +1243,9 @@ class SnippetViewSet(ModelViewSet): """ return None + def get_export_filename(self): + return self.export_filename or self.model_opts.db_table + def get_templates(self, action="index", fallback=""): """ Utility function that provides a list of templates to try for a given diff --git a/wagtail/test/testapp/wagtail_hooks.py b/wagtail/test/testapp/wagtail_hooks.py index 0e0b36e2ff..a987c5f5b4 100644 --- a/wagtail/test/testapp/wagtail_hooks.py +++ b/wagtail/test/testapp/wagtail_hooks.py @@ -264,6 +264,7 @@ class FullFeaturedSnippetViewSet(SnippetViewSet): "some_date", "first_published_at", ] + export_filename = "all-fullfeatured-snippets" index_template_name = "tests/fullfeaturedsnippet_index.html" ordering = ["text", "-_updated_at", "-pk"] add_to_admin_menu = True