Skip to content

Commit

Permalink
Add magazine viewset group (#1069)
Browse files Browse the repository at this point in the history
* Add archive issue viewset

* Fix magazine department slug auto-complete

* Add magazine department viewset

* Cleanup MagazineDepartment content panels

* Add magazine viewset group

* Add magazine issue viewset

* Add publication date filter
  • Loading branch information
brylie committed May 22, 2024
1 parent fa2150e commit dded8d8
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 197 deletions.
5 changes: 0 additions & 5 deletions magazine/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,6 @@ def get_context(


class MagazineDepartment(Page):
content_panels = [FieldPanel("title")]

# Hide the settings panels
settings_panels: list[str] = []

parent_page_types = ["MagazineDepartmentIndexPage"]
subpage_types: list[str] = []

Expand Down
110 changes: 108 additions & 2 deletions magazine/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,116 @@
from django.views.generic import DetailView

from .models import MagazineDepartment
import django_filters
from wagtail.admin.filters import DateRangePickerWidget
from wagtail.admin.viewsets.base import ViewSetGroup
from wagtail.admin.viewsets.pages import PageListingViewSet
from wagtail.admin.ui.tables import DateColumn
from wagtail.admin.ui.tables.pages import (
BulkActionsColumn,
PageTitleColumn,
PageStatusColumn,
)
from .models import (
ArchiveIssue,
MagazineDepartment,
MagazineIssue,
)


class MagazineDepartmentDetail(DetailView):
model = MagazineDepartment
context_object_name = "department"

template_name = "magazine/magazine_department_detail.html"


class MagazineIssueFilterSet(PageListingViewSet.filterset_class):
publication_date = django_filters.DateFromToRangeFilter(
label="Publication Date",
widget=DateRangePickerWidget,
)

class Meta:
model = MagazineIssue
fields = [
"publication_date",
]


class ArchiveIssueViewSet(PageListingViewSet):
model = ArchiveIssue
menu_label = "Archive Issues"
icon = "doc-full"
add_to_admin_menu = True
columns = [
PageTitleColumn(
"title",
label="Title",
sort_key="title",
),
DateColumn(
"publication_date",
label="Publication Date",
sort_key="publication_date",
),
PageStatusColumn(
"live",
label="Live",
sort_key="live",
),
BulkActionsColumn(
"bulk_actions",
label="Bulk Actions",
),
]
search_fields = (
"title",
"internet_archive_identifier",
)


archive_issue_viewset = ArchiveIssueViewSet("archive_issues")


class MagazineDepartmentViewSet(PageListingViewSet):
model = MagazineDepartment
menu_label = "Departments"
icon = "tag"
add_to_admin_menu = True
columns = [
PageTitleColumn(
"title",
label="Title",
sort_key="title",
),
BulkActionsColumn(
"bulk_actions",
label="Bulk Actions",
),
]
search_fields = ("title",)


magazine_department_viewset = MagazineDepartmentViewSet("magazine_departments")


class MagazineIssueViewSet(PageListingViewSet):
model = MagazineIssue
menu_label = "Issues"
icon = "doc-full-inverse"
add_to_admin_menu = True
search_fields = ("title",)
filterset_class = MagazineIssueFilterSet


magazine_issue_viewset = MagazineIssueViewSet("magazine_issues")


class MagazineViewSetGroup(ViewSetGroup):
menu_label = "Magazine"
menu_icon = "tablet-alt"
menu_order = 100
items = (
archive_issue_viewset,
magazine_department_viewset,
magazine_issue_viewset,
)
196 changes: 6 additions & 190 deletions magazine/wagtail_hooks.py
Original file line number Diff line number Diff line change
@@ -1,193 +1,9 @@
from django.urls import reverse
from django.utils.html import format_html
from wagtail_modeladmin.helpers import PageAdminURLHelper, PageButtonHelper
from wagtail_modeladmin.mixins import ThumbnailMixin
from wagtail_modeladmin.options import (
ModelAdmin,
ModelAdminGroup,
modeladmin_register,
from wagtail import hooks
from .views import (
MagazineViewSetGroup,
)

from .models import ArchiveIssue, MagazineDepartment, MagazineIssue


class MagazineIssueAdminURLHelper(PageAdminURLHelper):
def get_action_url(
self,
action,
*args,
**kwargs,
): # pragma: no cover
if action == "add-child":
url_name = "wagtailadmin_pages:add_subpage"
target_url = reverse(url_name, args=args, kwargs=kwargs)

return target_url

# for every other case - just call the parent method
return super().get_action_url(action, *args, **kwargs)


class MagazineIssueButtonHelperClass(PageButtonHelper):
add_child_button_classnames = ["add-child"]

def add_child_button(
self,
pk,
classnames_add=None,
classnames_exclude=None,
): # pragma: no cover
if classnames_add is None:
classnames_add = []
if classnames_exclude is None:
classnames_exclude = []

classnames = self.add_child_button_classnames + classnames_add
final_classnames = self.finalise_classname(classnames, classnames_exclude)

return {
"url": self.url_helper.get_action_url("add-child", pk),
"label": "Add Article",
"classname": final_classnames,
"title": f"Add article under this {self.verbose_name}",
}

def get_buttons_for_obj(
self,
obj,
exclude=None,
classnames_add=None,
classnames_exclude=None,
): # pragma: no cover
if exclude is None:
exclude = ([],)
if classnames_add is None:
classnames_add = ([],)
if classnames_exclude is None:
classnames_exclude = []

# call the parent class method to get the default set of buttons
buttons = super().get_buttons_for_obj(
obj,
exclude,
classnames_add,
classnames_exclude,
)

# set up some variables to do user checks and also get the primary key (id)
permission_helper = self.permission_helper
user = self.request.user
pk = getattr(obj, self.opts.pk.attname)

# many existing permission helpers are already available
# - see wagtail/contrib/modeladmin/helpers/permission.py
if "add-child" not in exclude and permission_helper.user_can_create(user):
add_child_button = self.add_child_button(
pk,
classnames_add,
classnames_exclude,
)
buttons.append(add_child_button)

return buttons


class MagazineIssueModelAdmin(ThumbnailMixin, ModelAdmin):
model = MagazineIssue
menu_icon = "doc-full-inverse"
menu_label = "Issues"
list_per_page = 10
ordering = [
"-publication_date",
]
list_display = (
"admin_thumb",
"title",
"publication_date",
"live",
"view_articles",
"add_article",
)
list_display_add_buttons = "title"
thumb_image_field_name = "cover_image"
thumb_image_filter_spec = "height-333"
thumb_col_header_text = "Cover"
thumb_default = "https://lorempixel.com/100/100"
list_filter = ("publication_date",)
empty_value_display = "-"
search_fields = ("title",)

button_helper_class = (
MagazineIssueButtonHelperClass # added to enable custom button generation
)
url_helper_class = (
MagazineIssueAdminURLHelper # added to enable custom url generation
)

def add_article(
self,
obj,
): # pragma: no cover
url_name = "wagtailadmin_pages:add_subpage"
url = reverse(url_name, args=[obj.id])

return format_html(
f'<a href="{url}" class="button button-small button-secondary">Add Article</a>', # noqa: E501
)

def view_articles(
self,
obj,
): # pragma: no cover
url_name = "wagtailadmin_explore"
url = reverse(url_name, args=[obj.id])

return format_html(
f'<a href="{url}" class="button button-small button-secondary">View Articles</a>', # noqa: E501
)


class ArchiveIssueModelAdmin(ModelAdmin):
model = ArchiveIssue
menu_icon = "doc-full"
menu_label = "Archive Issues"
list_per_page = 10
ordering = [
"publication_date",
]
list_display = (
"title",
"publication_date",
"internet_archive_identifier",
)
empty_value_display = "-"
search_fields = (
"title",
"internet_archive_identifier",
)


class MagazineDepartmentModelAdmin(ModelAdmin):
model = MagazineDepartment
menu_icon = "tag"
menu_label = "Departments"
menu_order = 200
add_to_settings_menu = False
exclude_from_explorer = False
list_per_page = 10
list_display = ("title",)
search_fields = ("title",)


class MagazineGroup(ModelAdminGroup):
menu_label = "Magazine"
menu_icon = "tablet-alt"
menu_order = 100
items = (
MagazineIssueModelAdmin,
ArchiveIssueModelAdmin,
MagazineDepartmentModelAdmin,
)


modeladmin_register(MagazineGroup)
@hooks.register("register_admin_viewset")
def register_magazine_viewset_group():
return MagazineViewSetGroup()

0 comments on commit dded8d8

Please sign in to comment.