title: Django: Custom Save method for Many-to-Many relation
body: <p>I need to set custom save and delete methods on a Many-to-Many relation.</p>
  
  <p>I tried specifying a model with the "through" attribute but this over-complicated my code and introduced some problems. I don't need any extra field on the Many-to-Many model, just custom save and delete methods.</p>
  
  <p>Is it possible to accomplish this without specifying the "through" attribute?</p>
  
  <p>Here's code:</p>
  
  <pre><code>class Order(BaseDate):
      #lots of fields
      relateds = models.ManyToManyField('RelatedProduct', verbose_name=_('related products'), blank=True, related_name='order_relateds', through='OrderRelateds')
      # more fields
      total = CurrencyField(verbose_name=_('total'))
  
      def calculate_total(self):
          cleanses = self.cleanse.taxed_price() * self.quantity
          delivery = DELIVERY_PRICE if self.delivery == 'delivery' else 0
          relateds = 0
          for r in self.relateds.all():
              relateds = relateds + float(r.taxed_price())
          total = float(cleanses) + delivery + relateds
          return total
  
      def save(self, *args, **kwargs):
          self.total = '%.2f' % self.calculate_total()
          super(Order, self).save(*args, **kwargs)
  
  class OrderRelateds(models.Model):
      order = models.ForeignKey(Order)
      relatedproduct = models.ForeignKey(RelatedProduct, verbose_name=_('related product'))
  
      class Meta:
          verbose_name = _('Related Product')
          verbose_name_plural = _('Products Related to this Order')
  
      def __unicode__(self):
          return self.relatedproduct.__unicode__()
  
      def save(self, *args, **kwargs):
          super(OrderRelateds, self).save(*args, **kwargs)
          self.order.save()
  
      def delete(self, *args, **kwargs):
          super(OrderRelateds, self).delete(*args, **kwargs)
          self.order.save()
  </code></pre>
  
  <p>I need to trigger recalculation of total price of the order if any related product (many to many item) is added to or removed from an order.</p>
  
  <p><strong>Edit: this is the code which solved my problem</strong></p>
  
  <pre><code>from django.db.models.signals import m2m_changed
  from django.dispatch import receiver
  
  @receiver(m2m_changed, sender=Order.relateds.through)
  def recalculate_total(sender, instance, action, **kwargs):
      """
      Automatically recalculate total price of an order when a related product is added or removed
      """
      if action == 'post_add':
          instance.save()
      if action == 'post_remove' or action == 'post_clear':
          instance.save()
  </code></pre>