Opened 11 years ago
Closed 10 years ago
#22594 closed Bug (fixed)
Content Type framework does not trigger Cascade delete
Reported by: | JoseTomasTocino | Owned by: | nobody |
---|---|---|---|
Component: | contrib.contenttypes | Version: | 1.6 |
Severity: | Normal | Keywords: | |
Cc: | chk | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I've posted this question in StackOverflow (http://stackoverflow.com/questions/23528296/djangos-content-type-framework-does-not-trigger-cascade-delete) and given it looks like a bug, I've decided to post it here.
Suppose the following models:
class DeltaCheck(models.Model): logs = generic.GenericRelation('Log') title = models.CharField(max_length=50) owner = models.ForeignKey(User) class Log(models.Model): title = models.CharField(max_length=50) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id')
If I create a DeltaCheck and a couple of Logs and then delete the DeltaCheck, the Logs are deleted as well:
In [7]: Log.objects.count() Out[7]: 10 In [8]: DeltaCheck.objects.get().delete() In [9]: Log.objects.count() Out[9]: 0
BUT if I delete the User (the field owner), the DeltaCheck gets deleted BUT not the Logs, look:
In [14]: Log.objects.count() Out[14]: 10 In [15]: DeltaCheck.objects.get().owner.delete() In [16]: DeltaCheck.objects.all() Out[16]: [] In [17]: Log.objects.count() Out[17]: 10
Is that proper behavior? I don't think so.
Change History (5)
comment:2 by , 11 years ago
Cc: | added |
---|
I'm able to reproduce the same issue with a similar database schema.
- django 1.6.1
- postgresql 9.1
As a workaround I've defined a pre_signal (but NOT empty as Jose says):
from django.db.models.signals import pre_delete from django.dispatch import receiver @receiver(pre_delete, sender=User) def pre_delete_receiver(sender, instance, **kwargs): ## CODE TO DELETE RELATED OBJECTS for delta in instance.deltachecks.all(): delta.logs.all().delete()
comment:3 by , 11 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Type: | Uncategorized → Bug |
Hi,
I can also reproduce this issue (and indeed, having an empty signal fixes the issue).
For reference, cascade deletion of generic foreign keys is documented and only works if you have a reverse GenericRelation
[1] (last two paragraphs).
The key to this issue probably lies in the fast_delete
method [2] (note for example the line 126 that explains why things behave differently if there is a signal listening or not).
Thanks.
[1] https://docs.djangoproject.com/en/1.6/ref/contrib/contenttypes/#django.contrib.contenttypes.generic.GenericRelation
[2] https://github.com/django/django/blob/master/django/db/models/deletion.py#L110
comment:4 by , 10 years ago
comment:5 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I can confirm that #22998 fixes the issue, closing as fixed.
Curiously, both pre_delete and post_delete signals are fired in the failing case... What happens in the middle?