Add docs and tests for exporting snippets listing

pull/10626/head
Sage Abdullah 2023-07-03 15:18:02 +01:00
rodzic 0a731b37f4
commit 428b7914e2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: EB1A33CC51CC0217
5 zmienionych plików z 102 dodań i 0 usunięć

Wyświetl plik

@ -87,6 +87,7 @@ Viewsets are Wagtail's mechanism for defining a group of related admin views wit
.. autoattribute:: menu_name
.. autoattribute:: menu_order
.. autoattribute:: list_display
.. autoattribute:: list_export
.. autoattribute:: list_filter
.. autoattribute:: filterset_class
.. autoattribute:: search_fields

Wyświetl plik

@ -93,6 +93,12 @@ 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.
```{versionadded} 5.1
The ability to export the listing view was added.
```
## Templates
For all views that are used for a snippet model, Wagtail looks for templates in the following directories within your project or app, before resorting to the defaults:

Wyświetl plik

@ -1,5 +1,8 @@
from datetime import datetime
from io import BytesIO
from unittest import mock
from django.conf import settings
from django.contrib.admin.utils import quote
from django.contrib.auth import get_permission_codename
from django.contrib.auth.models import Permission
@ -8,11 +11,13 @@ from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase, TransactionTestCase
from django.urls import reverse
from django.utils.timezone import now
from openpyxl import load_workbook
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.admin.menu import admin_menu, settings_menu
from wagtail.admin.panels import get_edit_handler
from wagtail.admin.staticfiles import versioned_static
from wagtail.admin.views.mixins import ExcelDateFormatter
from wagtail.blocks.field_block import FieldBlockAdapter
from wagtail.coreutils import get_dummy_request
from wagtail.models import Locale, Workflow, WorkflowContentType
@ -670,6 +675,88 @@ class TestListViewWithCustomColumns(BaseSnippetViewSetTests):
self.assertTagInHTML("<th>", html, count=5, allow_extra_attrs=True)
class TestListExport(BaseSnippetViewSetTests):
model = FullFeaturedSnippet
@classmethod
def setUpTestData(cls):
cls.model.objects.create(text="Pot Noodle", country_code="UK")
cls.some_date = now().date()
cls.first_published_at = "2023-07-01T13:12:11.100"
if settings.USE_TZ:
cls.first_published_at = "2023-07-01T13:12:11.100Z"
obj = cls.model.objects.create(
text="Indomie",
country_code="ID",
first_published_at=cls.first_published_at,
)
# Refresh so the first_published_at becomes a datetime object
obj.refresh_from_db()
cls.first_published_at = obj.first_published_at
def test_get_not_export_shows_export_buttons(self):
response = self.client.get(self.get_url("list"))
self.assertContains(response, "Download CSV")
self.assertContains(response, self.get_url("list") + "?export=csv")
self.assertContains(response, "Download XLSX")
self.assertContains(response, self.get_url("list") + "?export=xlsx")
def test_csv_export(self):
response = self.client.get(self.get_url("list"), {"export": "csv"})
self.assertEqual(response.status_code, 200)
data_lines = response.getvalue().decode().split("\n")
self.assertEqual(
data_lines[0],
"Text,Country Code,get_foo_country_code,Some Date,First Published At\r",
)
self.assertEqual(
data_lines[1],
f"Indomie,ID,Foo ID,{self.some_date.isoformat()},{self.first_published_at.isoformat(sep=' ')}\r",
)
self.assertEqual(
data_lines[2],
f"Pot Noodle,UK,Foo UK,{self.some_date.isoformat()},None\r",
)
def test_xlsx_export(self):
response = self.client.get(self.get_url("list"), {"export": "xlsx"})
self.assertEqual(response.status_code, 200)
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]
self.assertEqual(
cell_array[0],
[
"Text",
"Country Code",
"get_foo_country_code",
"Some Date",
"First Published At",
],
)
self.assertEqual(
cell_array[1],
[
"Indomie",
"ID",
"Foo ID",
self.some_date,
datetime(2023, 7, 1, 13, 12, 11, 100000),
],
)
self.assertEqual(
cell_array[2],
["Pot Noodle", "UK", "Foo UK", self.some_date, "None"],
)
self.assertEqual(len(cell_array), 3)
self.assertEqual(worksheet["E2"].number_format, ExcelDateFormatter().get())
class TestCustomTemplates(BaseSnippetViewSetTests):
model = FullFeaturedSnippet

Wyświetl plik

@ -669,6 +669,7 @@ class SnippetViewSet(ModelViewSet):
#: If ``filterset_class`` is set, this attribute will be ignored.
list_filter = None
#: 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 number of items to display per page in the index view. Defaults to 20.

Wyświetl plik

@ -257,6 +257,13 @@ class FullFeaturedSnippetViewSet(SnippetViewSet):
chooser_per_page = 15
filterset_class = FullFeaturedSnippetFilterSet
list_display = ["text", "country_code", "get_foo_country_code", UpdatedAtColumn()]
list_export = [
"text",
"country_code",
"get_foo_country_code",
"some_date",
"first_published_at",
]
index_template_name = "tests/fullfeaturedsnippet_index.html"
ordering = ["text", "-_updated_at", "-pk"]
add_to_admin_menu = True