Stage 4 — Custom list actions¶
Goal¶
Add a bulk action on the list view: select rows, pick a new category, apply to
all. Built-in bulk delete (from stage 0) works the same way — subclass
ListActionView, tag it list_action, and
append it to the controller routes.
Model¶
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
category = models.CharField(max_length=50, blank=True)
def __str__(self):
return self.title
Controller and registration¶
from django import forms
from django.utils.translation import gettext_lazy as _, ngettext
import djmvc
from .models import Post
class SetCategoryForm(forms.Form):
category = forms.CharField(max_length=50, label=_("Category"))
class SetCategoryView(djmvc.generic.ListActionView):
"""Bulk-update category on selected rows."""
title = _("Set category")
icon = "tag"
color = "info"
message = _("Choose a category for the selected posts.")
form_class = SetCategoryForm
def form_valid(self, form):
self.object_list.update(category=form.cleaned_data["category"])
return super().form_valid(form)
def get_form_valid_message(self):
count = self.object_list.count()
return ngettext(
"Updated category on %(count)d post.",
"Updated category on %(count)d posts.",
count,
) % {"count": count}
class PostController(djmvc.ModelController):
model = Post
icon = 'chat-square-text'
routes = djmvc.ModelController.routes + [
SetCategoryView,
]
djmvc.site.routes.append(PostController)
SetCategoryView receives selected primary keys as pks (query
string from the list action bar). object_list is the scoped queryset
intersection. form_valid runs your bulk logic — here a single
QuerySet.update.
User-visible strings use gettext and ngettext so success messages
pluralize correctly.
The list template discovers permitted actions as view.list_actions and
renders them in <list-action-bar> next to the default delete action.
Try it¶
Visit http://localhost:8000/post/, create a few posts, select rows, and click Set category:
Selected rows open the floating <list-action-bar> with permitted bulk
actions.¶
Custom SetCategoryView — same pattern as the built-in bulk
delete shown in Stage 0 — Register a model.¶
Tests¶
tests/test_stage4.py on GitHub
Next: Stage 5 — View mixins surveys the view mixins you can combine when building custom views.