from django.contrib.admin.actions import delete_selected

class YourModelAdmin(admin.ModelAdmin):
    def my_delete_selected(self, modeladmin, request, queryset):
        delete_orig = queryset.delete

        def _delete_closure():
            """
            The idea here is to wrap the original delete (gets called by
            delete_selected() when it does the actual deletion.
            """
            result = delete_orig()
            your_extra_functionality(request)
            return result
        queryset.delete = _delete_closure
        return delete_selected(modeladmin, request, queryset)

    def get_actions(self, request):
        'Patch delete_selected to have our version running'
        actions = super(YourModelAdmin, self).get_actions(request)
        actions['delete_selected'] = (
            self.my_delete_selected, 'delete_selected',
            delete_selected.short_description)
        return actions