#24738: Possible bug in m2m_changed signal when deleting related objects
----------------------------------------------+--------------------
Reporter: No-0n3 | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+--------------------
Hi,
Have observed that no m2m_changed signal is sent when a related object is
deleted.
If I explicitly clear the relations with "clear()" or remove the relation
with "remove()", m2m_changed is correctly sent but if I delete it without
calling "clear()" or "remove()" on the m2m field no signal is sent to
indicate a change in relationship.
Is this by design or should a m2m_changed signal be sent when a related
object is deleted from the m2m table at deletion when the relations also
are removed.
Right now I've done a workaround by catching the "pre_delete" signal on my
model that explicitly calls "clear()" on the M2M field to trigger the
signal and catching it with my other signal function when it gets a
"post_clear" action in m2m_changed signal.
Here are my models and signals with my workaround:
{{{
from django.db import models
from django.db.models.signals import m2m_changed, pre_delete
from django.dispatch import receiver
from django.db.models import Count
# Models
class Type(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return unicode(self.name)
class Blacklist(models.Model):
source = models.URLField()
name = models.CharField(max_length=200)
date_added = models.DateField(auto_now_add=True)
last_update = models.DateField(auto_now=True)
types = models.ManyToManyField(Type)
def __unicode__(self):
return unicode(self.name)
class Record(models.Model):
blacklists = models.ManyToManyField(Blacklist)
ip = models.GenericIPAddressField(protocol='IPv4', unique=True)
def __unicode__(self):
return unicode(self.ip)
# Signal actions
@receiver(m2m_changed, sender=Record.blacklists.through)
def blacklists_changed(sender, **kwargs):
if kwargs['action'] == "post_clear":
if kwargs['reverse']:
Record.objects.annotate(count=Count('blacklists')).exclude(count__gt=0).delete()
@receiver(pre_delete, sender=Blacklist)
def blacklist_deleted(sender, **kwargs):
kwargs['instance'].record_set.clear()
}}}
If you comment out the blacklist_deleted and do a <Blacklist
instance>.delete() no m2m_changed signal is sent at all.
BR / Isaac
--
Ticket URL: <https://code.djangoproject.com/ticket/24738>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/049.962d57c72f0148c070d77f4329e38559%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.