Skip to content

Commit

Permalink
Fix/post delete signal gets called twice for models in a foreign-key …
Browse files Browse the repository at this point in the history
…relation and cascade deletion constraint (#12)

* Extended _has_signal_listeners in BulkTrackerCollector

* Updates deletion logic to allow fast_delete

* Updates testcases

* Updates comments

---------

Co-authored-by: hassaanalansary <hassaanalansary@yahoo.com>
  • Loading branch information
MrAghyad and hassaanalansary authored Jul 24, 2024
1 parent 16bb769 commit 9eba00a
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 87 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

All notable changes to this project will be documented in this file.

## 0.2.1 (2024-07-24)
- A fix where `post_delete_signal()` was called twice for a model in a foreign-key relationship gets deleted with a cascade deletion constraint.

## 0.2.0 (2024-07-24)
- `post_delete_signal()` is now being sent if a parent model was deleted and triggered a cascade delete.

Expand Down
2 changes: 1 addition & 1 deletion bulk_tracker/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.0"
__version__ = "0.2.1"
6 changes: 6 additions & 0 deletions bulk_tracker/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@


class BulkTrackerCollector(Collector):

def delete(self, *, tracking_info_: TrackingInfo | None = None):
# sort instance collections
for model, instances in self.data.items():
Expand All @@ -29,8 +30,13 @@ def delete(self, *, tracking_info_: TrackingInfo | None = None):
if len(self.data) == 1 and len(instances) == 1:
instance = list(instances)[0]
if self.can_fast_delete(instance):
to_be_deleted = None
if post_delete_signal.has_listeners(model):
to_be_deleted = deepcopy(instance)
with transaction.mark_for_rollback_on_error(self.using):
count = sql.DeleteQuery(model).delete_batch([instance.pk], self.using)
if to_be_deleted:
send_post_delete_signal([to_be_deleted], model, tracking_info_)
setattr(instance, model._meta.pk.attname, None)
return count, {model._meta.label: count}

Expand Down
10 changes: 2 additions & 8 deletions bulk_tracker/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@
from bulk_tracker.collector import BulkTrackerCollector
from bulk_tracker.helper_objects import TrackingInfo
from bulk_tracker.managers import BulkTrackerManager
from bulk_tracker.signals import (
send_post_create_signal,
send_post_delete_signal,
send_post_update_signal,
)
from bulk_tracker.signals import send_post_create_signal, send_post_update_signal


class BulkTrackerModel(models.Model):
Expand Down Expand Up @@ -53,6 +49,4 @@ def delete(self, using=None, keep_parents=False, tracking_info_: TrackingInfo |
except TypeError:
collector = BulkTrackerCollector(using=using)
collector.collect([self], keep_parents=keep_parents)
ret = collector.delete(tracking_info_=tracking_info_)
send_post_delete_signal([self], model=self.__class__, tracking_info_=tracking_info_)
return ret
return collector.delete(tracking_info_=tracking_info_)
Loading

0 comments on commit 9eba00a

Please sign in to comment.