Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding HARD_DELETE action for SOFT_DELETE models in Admin panel #146

Open
bernardobgam opened this issue Dec 6, 2020 · 5 comments
Open

Comments

@bernardobgam
Copy link

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!

@helena238
Copy link

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.

@bernardobgam
Copy link
Author

@helena238 This would be great!

@Gagaro
Copy link
Member

Gagaro commented Feb 15, 2021

Feel free to open a pull request.

@Gagaro
Copy link
Member

Gagaro commented Feb 15, 2021

Actually this is a duplicate of #88, I'll close the older one.

@EBI3827
Copy link

EBI3827 commented May 26, 2021

@helena238 thank you for your great improvement , where should I find hard_delete_template.html? or I myself must create it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants