How to perform action on model instance delete?

Currently I have this “on create“ and “on delete“, “on create“ works fine, but “on delete“ only works when models are deleted one by one and not when deleted in bulk. Is there a way to make the custom action work when deleting in bulk? (deleting in bulk means, for example: in admin, when selecting multiple objects and clicking delete selected objects)

class AnalyticsTimestamp(models.Model):
    metric = models.ForeignKey(AnalyticsMetric, on_delete=models.CASCADE, related_name='timestamps')
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='analytics_timestamps')
    date = models.DateTimeField(auto_now_add=True)
    resolved = models.BooleanField(default=False)

    def resolve(self):  # If the issue of the user was resolved lower the priority, so the user is no longer in top users and no longer asked if they have any problem
        self.user.priority -= self.metric.priority
        self.user.save()
        self.resolved = True
        self.save()

    def save(self, *args, **kwargs):
        if not self.pk:  # on creation
            now_date = timezone.now().date()
            self.user.priority += self.metric.priority
            self.user.save()
            daily, _ = AnalyticsDaily.objects.get_or_create(metric=self.metric, date=date(now_date.year, now_date.month, now_date.day))
            daily.value += 1
            daily.save()
            monthly, _ = AnalyticsMonthly.objects.get_or_create(metric=self.metric, date=date(now_date.year, now_date.month, 1))
            monthly.value += 1
            monthly.save()
        super().save(*args, **kwargs)


    def delete(self, *args, **kwargs):
        if not self.resolved:  # decrement user priority on model delete if problem of the user hasn't resolved, but timestamp is being deleted
            self.user.priority -= self.metric.priority
            self.user.save()
        super().delete(*args, **kwargs)

I think you have two options:

First, override the delete() method of the model’s Manager. This is called when multiple objects are being deleted, so you could add some custom logic in there before calling super().delete(*args, **kwargs) to continue the default behaviour.

Or, as the warning at the end of this section in the docs suggests, you could use Signals, and hook into either the pre_delete or post_delete signal.

Which is best depends on various factors. A lot of people aren’t keen on using Signals because it does “hide” important functionality away from the models.

In addition to the options listed above, there is a third that I think would be worth considering - create your own “Bulk Delete” action for that object. (See the yellow Note box near the top of Admin actions | Django documentation | Django)

It avoids the need for a signal and can be used to make it obvious that there is something different being done when deleting objects in the admin.

>>> blogs = Blog.objects.all()

# This will delete all Blogs and all of their Entry objects.
>>> blogs.delete()
(5, {'blog.Blog': 1, 'blog.Entry': 2, 'blog.Entry_authors': 2})

This cascade behavior is customizable via the on_delete argument to the ForeignKey.

The delete() method does a bulk delete and does not call any delete() methods on your models. It does, however, emit the pre_delete and post_delete signals for all deleted objects (including cascaded deletions).

Overriding delete will not help as bulk delete will just perform an SQL query, without running any custom code. Documentation says that signals will also be called on bulk delete. So I think I will use signals, thank you for help. (If I’ve misunderstood your answer feel free to correct me)