Action which deletes the selected files and/or folders.

        This action first displays a confirmation page whichs shows all the
        deleteable files and/or folders, or, if the user has no permission on
        one of the related childs (foreignkeys), a "permission denied" message.

        Next, it deletes all selected files and/or folders and redirects back to
        the folder.

def delete_files_or_folders(self, request, files_queryset, folders_queryset):
        """
        Action which deletes the selected files and/or folders.

        This action first displays a confirmation page whichs shows all the
        deleteable files and/or folders, or, if the user has no permission on
        one of the related childs (foreignkeys), a "permission denied" message.

        Next, it deletes all selected files and/or folders and redirects back to
        the folder.
        """
        opts = self.model._meta
        app_label = opts.app_label

        # Check that the user has delete permission for the actual model
        if not self.has_delete_permission(request):
            raise PermissionDenied

        current_folder = self._get_current_action_folder(
            request, files_queryset, folders_queryset)

        all_protected = []

        # Populate deletable_objects, a data structure of all related objects
        # that will also be deleted. Hopefully this also checks for necessary
        # permissions.
        # TODO: Check if permissions are really verified
        using = router.db_for_write(self.model)
        deletable_files, model_count_files, perms_needed_files, protected_files = get_deleted_objects(files_queryset, files_queryset.model._meta, request.user, self.admin_site, using)
        deletable_folders, model_count_folder, perms_needed_folders, protected_folders = get_deleted_objects(folders_queryset, folders_queryset.model._meta, request.user, self.admin_site, using)
        all_protected.extend(protected_files)
        all_protected.extend(protected_folders)

        all_deletable_objects = [deletable_files, deletable_folders]
        all_perms_needed = perms_needed_files.union(perms_needed_folders)

        # The user has already confirmed the deletion. Do the deletion and
        # return a None to display the change list view again.
        if request.POST.get('post'):
            if all_perms_needed:
                raise PermissionDenied
            n = files_queryset.count() + folders_queryset.count()
            if n:
                # delete all explicitly selected files
                for f in files_queryset:
                    self.log_deletion(request, f, force_text(f))
                    f.delete()
                # delete all files in all selected folders and their children
                # This would happen automatically by ways of the delete
                # cascade, but then the individual .delete() methods won't be
                # called and the files won't be deleted from the filesystem.
                folder_ids = set()
                for folder in folders_queryset:
                    folder_ids.add(folder.id)
                    folder_ids.update(
                        folder.get_descendants().values_list('id', flat=True))
                for f in File.objects.filter(folder__in=folder_ids):
                    self.log_deletion(request, f, force_text(f))
                    f.delete()
                # delete all folders
                for f in folders_queryset:
                    self.log_deletion(request, f, force_text(f))
                    f.delete()
                self.message_user(request, _("Successfully deleted %(count)d files and/or folders.") % {"count": n, })
            # Return None to display the change list page again.
            return None

        if all_perms_needed or all_protected:
            title = _("Cannot delete files and/or folders")
        else:
            title = _("Are you sure?")

        context = self.admin_site.each_context(request)
        context.update({
            "title": title,
            "instance": current_folder,
            "breadcrumbs_action": _("Delete files and/or folders"),
            "deletable_objects": all_deletable_objects,
            "files_queryset": files_queryset,
            "folders_queryset": folders_queryset,
            "perms_lacking": all_perms_needed,
            "protected": all_protected,
            "opts": opts,
            'is_popup': popup_status(request),
            'filer_admin_context': AdminContext(request),
            "root_path": reverse('admin:index'),
            "app_label": app_label,
            "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME,
        })

        # Display the destination folder selection page
        return render(
            request,
            "admin/filer/delete_selected_files_confirmation.html",
            context
        )