﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
24738	Possible bug in m2m_changed signal when deleting related objects	No-0n3	nobody	"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"	Bug	new	Database layer (models, ORM)	1.8	Normal				Unreviewed	0	0	0	0	0	0
