Open bernardobgam opened 3 years ago
Hi! I also needed the hard delete admin action in my project. I have extended the SafeDeleteAdmin class as follows:
from safedelete.admin import SafeDeleteAdmin
from safedelete.models import HARD_DELETE
from safedelete.utils import related_objects
from django.contrib import admin, messages
from django.template.response import TemplateResponse
from django.contrib.admin.utils import model_ngettext
from django.utils.encoding import force_text
from django.core.exceptions import PermissionDenied
class SafeDeleteAdminExtended(SafeDeleteAdmin):
hard_delete_template = "hard_delete_template.html"
actions = ['undelete_selected', 'hard_delete', ]
def hard_delete(self, request, queryset):
""" Admin action to delete objects finally. """
if not self.has_delete_permission(request):
raise PermissionDenied
original_queryset = queryset.all()
queryset = queryset.filter(deleted__isnull=False)
if request.POST.get('post'):
requested = original_queryset.count()
changed = queryset.count()
if changed:
for obj in queryset:
obj.delete(force_policy=HARD_DELETE)
if requested > changed:
self.message_user(
request,
"Successfully hard deleted %(count_changed)d of the "
"%(count_requested)d selected %(items)s." % {
"count_requested": requested,
"count_changed": changed,
"items": model_ngettext(self.opts, requested)
},
messages.WARNING,
)
else:
self.message_user(
request,
"Successfully hard deleted %(count)d %(items)s." % {
"count": changed,
"items": model_ngettext(self.opts, requested)
},
messages.SUCCESS,
)
else:
self.message_user(
request,
"No permission for hard delete. Execute soft delete first.",
messages.ERROR
)
return None
opts = self.model._meta
if len(original_queryset) == 1:
objects_name = force_text(opts.verbose_name)
else:
objects_name = force_text(opts.verbose_name_plural)
title = "Are you sure?"
deletable_objects, model_count, perms_needed, protected = self.get_deleted_objects(queryset, request)
context = {
'title': title,
'objects_name': objects_name,
'queryset': queryset,
'original_queryset': original_queryset,
'opts': opts,
'app_label': opts.app_label,
'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
'model_count': dict(model_count).items(),
'deletable_objects': [deletable_objects],
'perms_lacking': perms_needed,
'protected': protected,
'media': self.media,
}
return TemplateResponse(
request,
self.hard_delete_template,
context,
)
hard_delete.short_description = "Hard delete selected %(verbose_name_plural)s."
If there is interest I can integrate my solution in the existing framework.
@helena238 This would be great!
Feel free to open a pull request.
Actually this is a duplicate of #88, I'll close the older one.
@helena238 thank you for your great improvement , where should I find hard_delete_template.html? or I myself must create it?
It would be very helpful to be able to manually HARD DELETE objects in the admin panel which have a SOFT_DELETE or SOFT_DELETE_CASCADE policy.
Thank you for your project!