from typing import Any, cast from django.db.models import Count, Q from django.utils.translation import gettext_lazy as _ from django.utils.translation import ngettext from wagtail import hooks from wagtail.admin.ui.tables import BooleanColumn, Column from wagtail.snippets.bulk_actions.snippet_bulk_action import SnippetBulkAction from wagtail.snippets.models import register_snippet from wagtail.snippets.permissions import get_permission_name from wagtail.snippets.views.snippets import SnippetViewSet from apps.comments.models import Comment class ApproveCommentBulkAction(SnippetBulkAction): display_name = _("Approve") action_type = "approve" aria_label = _("Approve selected comments") template_name = "comments/confirm_bulk_approve.html" action_priority = 20 models = [Comment] def check_perm(self, snippet): if getattr(self, "can_change_items", None) is None: self.can_change_items = self.request.user.has_perm(get_permission_name("change", self.model)) return self.can_change_items @classmethod def execute_action(cls, objects, **kwargs): updated = kwargs["self"].model.objects.filter(pk__in=[obj.pk for obj in objects], is_approved=False).update( is_approved=True ) return updated, 0 def get_success_message(self, num_parent_objects, num_child_objects): return ngettext( "%(count)d comment approved.", "%(count)d comments approved.", num_parent_objects, ) % {"count": num_parent_objects} class UnapproveCommentBulkAction(SnippetBulkAction): display_name = _("Unapprove") action_type = "unapprove" aria_label = _("Unapprove selected comments") template_name = "comments/confirm_bulk_unapprove.html" action_priority = 30 models = [Comment] def check_perm(self, snippet): if getattr(self, "can_change_items", None) is None: self.can_change_items = self.request.user.has_perm(get_permission_name("change", self.model)) return self.can_change_items @classmethod def execute_action(cls, objects, **kwargs): updated = kwargs["self"].model.objects.filter(pk__in=[obj.pk for obj in objects], is_approved=True).update( is_approved=False ) return updated, 0 def get_success_message(self, num_parent_objects, num_child_objects): return ngettext( "%(count)d comment unapproved.", "%(count)d comments unapproved.", num_parent_objects, ) % {"count": num_parent_objects} class CommentViewSet(SnippetViewSet): model = Comment queryset = Comment.objects.all() icon = "comment" list_display = [ "author_name", "article", BooleanColumn("is_approved"), Column("pending_in_article", label="Pending (article)"), "created_at", ] list_filter = ["is_approved"] search_fields = ["author_name", "body"] add_to_admin_menu = True def get_queryset(self, request): base_qs = self.model.objects.all().select_related("article", "parent") # mypy-django-plugin currently crashes on QuerySet.annotate() in this file. typed_qs = cast(Any, base_qs) return typed_qs.annotate( pending_in_article=Count( "article__comments", filter=Q(article__comments__is_approved=False), distinct=True, ) ) register_snippet(CommentViewSet) hooks.register("register_bulk_action", ApproveCommentBulkAction) hooks.register("register_bulk_action", UnapproveCommentBulkAction)