Enhancing Django comments admin with django-batchadmin

So, I'm making headway against comment spam, but still accumulating a bunch of comments that are suspicious enough to mark for review, but not bad enough to reject out of hand. The find, delete, confirm delete cycle in the admin interface is tiresome.

Enter django-batchadmin, a sweet, simple enhancement to the Django admin that enables batch actions on model instances.

It comes with a batch delete action which solves my problem out of the box: filter comments down to those not marked public, select all, delete, go, done. But it's also trivial to create your own actions, so I can now also select a bunch of comments that aren't spam and mark them public. Very, very cool.

And it's going to be in Django 1.1. Perfect.

Once you have django-batchadmin installed, here's a quick admin.py to add batch actions for comments. Adding support for flags should be straightforward, but I don't use them, so that's an exercise for the reader.

from django.contrib import admin
from django.contrib.comments.admin import CommentsAdmin
from django.contrib.comments.models import Comment

from batchadmin.admin import BatchModelAdmin, CHECKBOX_NAME
from batchadmin.util import model_ngettext

def get_selected(request, changelist):
    selected = request.POST.getlist(CHECKBOX_NAME)
    return changelist.get_query_set().filter(pk__in=selected)

# Override default Comment admin to allow batch changes
class BatchCommentsAdmin(CommentsAdmin, BatchModelAdmin):
    batch_actions = ['delete_selected', 'mark_not_public', 'mark_public', 'mark_not_removed', 'mark_removed']

    def mark_not_public(self, request, changelist):
        comments = get_selected(request, changelist)
        n = comments.count()
        if n:
            for comment in comments:
                comment.is_public = False
                comment.save()
            self.message_user(request, "Marked %d %s not public." % (n, model_ngettext(self.opts, n)))

    def mark_public(self, request, changelist):
        comments = get_selected(request, changelist)
        n = comments.count()
        if n:
            for comment in comments:
                comment.is_public = True
                comment.save()
            self.message_user(request, "Marked %d %s public." % (n, model_ngettext(self.opts, n)))

    def mark_not_removed(self, request, changelist):
        comments = get_selected(request, changelist)
        n = comments.count()
        if n:
            for comment in comments:
                comment.is_removed = False
                comment.save()
            self.message_user(request, "Marked %d %s not removed." % (n, model_ngettext(self.opts, n)))

    def mark_removed(self, request, changelist):
        comments = get_selected(request, changelist)
        n = comments.count()
        if n:
            for comment in comments:
                comment.is_removed = True
                comment.save()
            self.message_user(request, "Marked %d %s removed." % (n, model_ngettext(self.opts, n)))

admin.site.unregister(Comment)
admin.site.register(Comment, BatchCommentsAdmin)

comments (3)

Josh

13 December 2008

1:56

united states United States

Neat stuff!! You mentioned that this feature will be in Django 1.1... will it just be for comments, or will it be more generic (applicable to "any" model)? THAT is what I want.

Florian Apolloner

13 December 2008

3:25

austria Austria

@Josh:
It's already generic, John just explained how you would use it for comment moderation, but you can do what you want with it. For more information check the docs at: http://code.google.com/p/django-batchadmin/wiki/GettingStarted

rong

17 February 2009

8:17

viet nam Viet Nam

hay qua tuyet voi qua

Comments have been turned off for this article, but you can always contact us about it.