Signal for M2M changed on a through field

933 views Asked by At

Before switching my M2M field to a through field I had this signal that would call methods on the instance to update some of its values. But I switched to a 'through' type M2M and it stopped functioning. I have a work around by calling those functions in my serializer, but that is kind of nasty. How do I fix it?

Signal

@receiver(m2m_changed, sender=Order.items.through)
def update_order_when_items_changed(sender, instance, **kwargs):
    instance.set_weight()
    instance.set_total_price()
    instance.save()

Current Models

class OrderItem(models.Model):
    order = models.ForeignKey('main.Order')
    item = models.ForeignKey('main.Item')
    quantity = models.IntegerField(default=1)


class Order(models.Model):
    user = models.ForeignKey("main.ShopUser")
    items = models.ManyToManyField("main.Item", through='main.OrderItem')
    placed = models.BooleanField(default=False)
    date_placed = models.DateTimeField(null=True, blank=True)
1

There are 1 answers

0
Jared Mackey On BEST ANSWER

I feel silly for not figuring this out before. Instead of m2m_changed signal use the post_save and post_delete on the through model and it should essentially do the same thing. Then in my serializer just remove the instance.save() if I am not doing other changes.

@receiver((post_save, post_delete), sender="main.OrderItem")
def update_order_when_items_changed(sender, instance, **kwargs):
    instance.order.set_weight()
    instance.order.set_total_price()
    instance.order.save()