django-admin2/djadmin2/actions.py
Danilo Bargen 39aaacccb6 PEP8
2013-07-06 09:37:25 +02:00

128 lines
4.1 KiB
Python

from django.contrib import messages
from django.views.generic import TemplateView
from django.utils.encoding import force_text
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy
from django.utils.translation import ugettext as _
from . import permissions, utils
from .viewmixins import AdminModel2Mixin
def get_description(action):
if hasattr(action, 'description'):
return action.description
else:
return capfirst(action.__name__.replace('_', ' '))
class BaseListAction(AdminModel2Mixin, TemplateView):
permission_classes = (permissions.IsStaffPermission,)
empty_message = 'Items must be selected in order to perform actions on them. ' + \
'No items have been changed.'
success_message = 'Successfully deleted %d %s'
queryset = None
def __init__(self, queryset, *args, **kwargs):
self.queryset = queryset
self.model = queryset.model
options = utils.model_options(self.model)
self.app_label = options.app_label
self.model_name = options.module_name
self.item_count = len(queryset)
if self.item_count <= 1:
objects_name = options.verbose_name
else:
objects_name = options.verbose_name_plural
self.objects_name = unicode(objects_name)
super(BaseListAction, self).__init__(*args, **kwargs)
def get_queryset(self):
""" Replaced `get_queryset` from `AdminModel2Mixin`"""
return self.queryset
def description(self):
raise NotImplementedError("List action classes require"
" a description attribute.")
@property
def default_template_name(self):
raise NotImplementedError(
"List actions classes using display_nested_response"
" require a template"
)
def get_context_data(self, **kwargs):
""" Utility method when you want to display nested objects
(such as during a bulk update/delete)
"""
context = super(BaseListAction, self).get_context_data()
def _format_callback(obj):
opts = utils.model_options(obj)
return '%s: %s' % (force_text(capfirst(opts.verbose_name)),
force_text(obj))
collector = utils.NestedObjects(using=None)
collector.collect(self.queryset)
context.update({
'view': self,
'objects_name': self.objects_name,
'queryset': self.queryset,
'deletable_objects': collector.nested(_format_callback),
})
return context
def get(self, request):
if self.item_count > 0:
return super(BaseListAction, self).get(request)
message = _(self.empty_message)
messages.add_message(request, messages.INFO, message)
return None
def post(self, request):
if request.POST.get('confirmed'):
if self.process_queryset() is None:
message = _(self.success_message % (
self.item_count, self.objects_name)
)
messages.add_message(request, messages.INFO, message)
return None
else:
# The user has not confirmed that they want to delete the objects, so
# render a template asking for their confirmation.
return self.get(request)
def process_queryset(self):
raise NotImplementedError('Must be provided to do some actions with queryset')
class DeleteSelectedAction(BaseListAction):
# TODO: Check that user has permission to delete all related obejcts. See
# `get_deleted_objects` in contrib.admin.util for how this is currently
# done. (Hint: I think we can do better.)
default_template_name = "actions/delete_selected_confirmation.html"
description = ugettext_lazy("Delete selected items")
permission_classes = BaseListAction.permission_classes + (
permissions.ModelDeletePermission,
)
def process_queryset(self):
# The user has confirmed that they want to delete the objects.
self.get_queryset().delete()