kopia lustrzana https://github.com/wagtail/wagtail
Add docs and tests for exporting snippets listing
rodzic
0a731b37f4
commit
428b7914e2
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue