Need details re: deletion of a referenced model instance

9 views
Skip to first unread message

Jeff Blaine

unread,
Feb 14, 2012, 2:02:11 PM2/14/12
to django...@googlegroups.com
Hi all,

I'm having trouble detecting changes that happen to a M2M field behind the scenes: as a result of one of the *referenced objects being deleted*

I'm using Django 1.3.1 with PostgreSQL 8

Let's say we have the following simple proof of concept models:

class Topping(models.Model):
    name = models.CharField()

class Pizza(models.Model):
    name = models.CharField()
    toppings = models.ManyToManyField(Topping, null=true, blank=true)

And this data established using those models:

    TOPPING
    id=1, name="Pepperoni"
    id=2, name="Onion"
    id=3, name="Mushroom"

    PIZZA
    id=1, name="foopizza"
    toppings=1,2,3

Known Facts:

1. Deleting any Topping object (for example, deleting id=1, name="Pepperoni") also removes it from foopizza.toppings.  Good.
2. No m2m_changed signal is sent when 1 (above happens).  BAD.

How do I tie into "topping *object* was deleted (no longer for sale), perform custom code on ALL Pizza objects that referenced it" ?

Register a post_delete signal for Topping?  How do I refer to or find the Pizza objects that referred to it?

akaariai

unread,
Feb 14, 2012, 4:50:16 PM2/14/12
to Django users
It seems like an oversight that no m2m_changed signal is generated in
this case. I think this is worth a ticket in trac (https://
code.djangoproject.com/newticket).

The problem is that you can't collect the related Pizzas from the
post_delete signal. The m2m relations are already deleted at that
point. If you can just do the processing in the pre_delete signal then
things are much easier, as you can just use instance.pizza_set.all()
to get the related objects.

- Anssi

Marc Aymerich

unread,
Feb 14, 2012, 6:37:43 PM2/14/12
to django...@googlegroups.com
On Tue, Feb 14, 2012 at 8:02 PM, Jeff Blaine <cjbl...@gmail.com> wrote:
> Hi all,
>
> I'm having trouble detecting changes that happen to a M2M field behind the
> scenes: as a result of one of the *referenced objects being deleted*
>
> I'm using Django 1.3.1 with PostgreSQL 8
>
> Let's say we have the following simple proof of concept models:
>
> class Topping(models.Model):
>     name = models.CharField()
>
> class Pizza(models.Model):
>     name = models.CharField()
>     toppings = models.ManyToManyField(Topping, null=true, blank=true)
>
> And this data established using those models:
>
>     TOPPING
>     id=1, name="Pepperoni"> Register a post_delete signal for Topping?  How do I refer to or find the

>     id=2, name="Onion"
>     id=3, name="Mushroom"
>
>     PIZZA
>     id=1, name="foopizza"
>     toppings=1,2,3
>
> Known Facts:
>
> 1. Deleting any Topping object (for example, deleting id=1,
> name="Pepperoni") also removes it from foopizza.toppings.  Good.
> 2. No m2m_changed signal is sent when 1 (above happens).  BAD.
>
> How do I tie into "topping *object* was deleted (no longer for sale),
> perform custom code on ALL Pizza objects that referenced it" ?
>
> Register a post_delete signal for Topping?  How do I refer to or find the
> Pizza objects that referred to it?
>

You can introspect topping model looking for pizza m2m relation-like:
take a look at Topping._meta attribute, and then send a custom signal
for each related objects when a topping is deleted.

--
Marc

Marc Aymerich

unread,
Feb 15, 2012, 4:39:28 AM2/15/12
to django...@googlegroups.com

Jeff Blaine

unread,
Feb 15, 2012, 8:57:51 AM2/15/12
to django...@googlegroups.com
>> Known Facts:
>>
>> 1. Deleting any Topping object (for example, deleting id=1,
>> name="Pepperoni") also removes it from foopizza.toppings.  Good.
>> 2. No m2m_changed signal is sent when 1 (above happens).  BAD.

...

Already checked it out before posting.  See '2' above.


Thank you Marc and Anssi!
Reply all
Reply to author
Forward
0 new messages