1

I have a 'notes' model in my Django app where I've built some custom delete actions:

class Note(models.Model):
    [MODEL FIELDS HERE]

    def delete(self, *args, **kwargs):
        [STUFF HEPPENS HERE]
        super(Note, self).delete()

If I click into the individual note from the Django admin and hit the 'Delete' button, the custom delete actions work just fine, but if I check the box next to the note in the list view and choose 'Delete selected notes' from the dropdown, they do not.

What am I missing here?

campegg
  • 123
  • 1
  • 1
  • 11
  • 1
    This is because bulk delete operations are handled differently compared to deleting single objects in the admin. If you delete one object, django admin calls your model's `delete` method, but if you delete multiple ones from the list view, the queryset manager's delete is called instead (where the model's delete method is not called). The related code can be found [here](https://github.com/django/django/blob/main/django/contrib/admin/options.py#L1228-L1236) – Brian Destura Jul 25 '22 at 00:09
  • 1
    Ah, that's definitely news to me. Thank you! – campegg Jul 25 '22 at 12:23

2 Answers2

1

delete selected is a bulk action and for efficiency reasons Django deletes the whole queryset at once, not calling the delete() method on each model instance.

If you need to make sure it does get called, e.g. you have some custom handling there that should not be skipped, just override the delete_queryset method on your ModelAdmin subclass like this:

# content of admin.py in your Django app

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):
    def delete_queryset(self, request, queryset):
        for obj in queryset.all():
            obj.delete()
knaperek
  • 2,113
  • 24
  • 39
0

See @Brian Destura's answer in the comments above.

campegg
  • 123
  • 1
  • 1
  • 11