from django.utils import timezone from django.utils.translation import gettext, gettext_lazy as _ from django.utils.translation import ngettext from wagtail.admin.ui.tables import Column, DateColumn from wagtail.admin.ui.tables.pages import PageStatusColumn, PageTitleColumn from wagtail.admin.views.pages.listing import ExplorableIndexView, IndexView from wagtail.admin.viewsets.pages import PageListingViewSet, PageViewSet from dnscms.admin import ListingRedirectChooseParentView from events.models import EventPage class EventDateColumn(Column): def get_value(self, instance): occurrences = list(instance.occurrences.order_by("start")) if not occurrences: return "—" if len(occurrences) == 1: local = timezone.localtime(occurrences[0].start) return local.strftime(gettext("%Y-%m-%d at %H:%M")) count = len(occurrences) return ngettext("%(count)d occurrence", "%(count)d occurrences", count) % {"count": count} class OrganizersColumn(Column): def get_value(self, instance): names = list(instance.organizers.values_list("name", flat=True)) if not names: return "—" if len(names) == 1: return names[0] return f"{names[0]} (+{len(names) - 1})" class EventPagePrefetchMixin: """Prefetch the relations the event columns read, so the listing avoids N+1.""" def annotate_queryset(self, pages): pages = super().annotate_queryset(pages) return pages.prefetch_related( "occurrences", "organizer_links__organizer", ) class EventPageIndexView(EventPagePrefetchMixin, IndexView): pass class EventPageExplorableIndexView(EventPagePrefetchMixin, ExplorableIndexView): pass class EventChooseParentView(ListingRedirectChooseParentView): listing_url_name = "events:index" class EventListingMixin: """Shared model + columns for the standalone listing and the page explorer.""" model = EventPage icon = "date" columns = [ PageTitleColumn("title", label=_("Title"), sort_key="title", classname="title"), EventDateColumn("event_date", label=_("Date"), width="13%"), OrganizersColumn("organizers", label=_("Organizers"), width="12%"), DateColumn( "latest_revision_created_at", label=_("Updated"), sort_key="latest_revision_created_at", width="10%", ), PageStatusColumn("status", label=_("Status"), sort_key="live", width="10%"), ] class EventSidebarViewSet(EventListingMixin, PageListingViewSet): """Standalone 'Events' sidebar entry, reached independently of the page tree.""" index_view_class = EventPageIndexView choose_parent_view_class = EventChooseParentView menu_label = _("Events") menu_order = 1 add_to_admin_menu = True ordering = "-latest_revision_created_at" class EventExplorerViewSet(EventListingMixin, PageViewSet): """Applies the same columns when navigating into EventIndex via the page explorer.""" index_view_class = EventPageExplorableIndexView event_sidebar_viewset = EventSidebarViewSet("events") event_explorer_viewset = EventExplorerViewSet()