actions.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. """
  2. Built-in, globally-available admin actions.
  3. """
  4. from django.contrib import messages
  5. from django.contrib.admin import helpers
  6. from django.contrib.admin.decorators import action
  7. from django.contrib.admin.utils import model_ngettext
  8. from django.core.exceptions import PermissionDenied
  9. from django.template.response import TemplateResponse
  10. from django.utils.translation import gettext as _, gettext_lazy
  11. @action(
  12. permissions=['delete'],
  13. description=gettext_lazy('Delete selected %(verbose_name_plural)s'),
  14. )
  15. def delete_selected(modeladmin, request, queryset):
  16. """
  17. Default action which deletes the selected objects.
  18. This action first displays a confirmation page which shows all the
  19. deletable objects, or, if the user has no permission one of the related
  20. childs (foreignkeys), a "permission denied" message.
  21. Next, it deletes all selected objects and redirects back to the change list.
  22. """
  23. opts = modeladmin.model._meta
  24. app_label = opts.app_label
  25. # Populate deletable_objects, a data structure of all related objects that
  26. # will also be deleted.
  27. deletable_objects, model_count, perms_needed, protected = modeladmin.get_deleted_objects(queryset, request)
  28. # The user has already confirmed the deletion.
  29. # Do the deletion and return None to display the change list view again.
  30. if request.POST.get('post') and not protected:
  31. if perms_needed:
  32. raise PermissionDenied
  33. n = queryset.count()
  34. if n:
  35. for obj in queryset:
  36. obj_display = str(obj)
  37. modeladmin.log_deletion(request, obj, obj_display)
  38. modeladmin.delete_queryset(request, queryset)
  39. modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % {
  40. "count": n, "items": model_ngettext(modeladmin.opts, n)
  41. }, messages.SUCCESS)
  42. # Return None to display the change list page again.
  43. return None
  44. objects_name = model_ngettext(queryset)
  45. if perms_needed or protected:
  46. title = _("Cannot delete %(name)s") % {"name": objects_name}
  47. else:
  48. title = _("Are you sure?")
  49. context = {
  50. **modeladmin.admin_site.each_context(request),
  51. 'title': title,
  52. 'objects_name': str(objects_name),
  53. 'deletable_objects': [deletable_objects],
  54. 'model_count': dict(model_count).items(),
  55. 'queryset': queryset,
  56. 'perms_lacking': perms_needed,
  57. 'protected': protected,
  58. 'opts': opts,
  59. 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
  60. 'media': modeladmin.media,
  61. }
  62. request.current_app = modeladmin.admin_site.name
  63. # Display the confirmation page
  64. return TemplateResponse(request, modeladmin.delete_selected_confirmation_template or [
  65. "admin/%s/%s/delete_selected_confirmation.html" % (app_label, opts.model_name),
  66. "admin/%s/delete_selected_confirmation.html" % app_label,
  67. "admin/delete_selected_confirmation.html"
  68. ], context)