0
class Lab(Model):
  pass

class School(Model):
  labs = ManyToManyField(Lab, related_name='schools')

def m2m_changed_labs(*args, **kwargs):
  pass

m2m_changed.connect(m2m_changed_labs, sender=Lab.schools)

The m2m_changed signal is never triggered, therefore the m2m_changed_labs function is never called. I want the m2m_changed_labs function to be called each time a school is added to or removed from a lab.

Chillar Anand
  • 27,936
  • 9
  • 119
  • 136
user2282405
  • 873
  • 2
  • 9
  • 10

1 Answers1

0

Have you tried sender=School.labs.through?

and with your receiver method like this:

def m2m_changed_labs(sender, **kwargs):  # notice sender instead of *args
    print "signal received"

That's the sender used in the example from the docs.

Adrián
  • 6,135
  • 1
  • 27
  • 49
  • First: `AttributeError: 'ManyRelatedObjectsDescriptor' object has no attribute 'through'` And second is never trigger either. – user2282405 May 15 '13 at 12:47
  • @user2282405 could you try with the direct field instead of the related name? The docs clearly state that the sender must be: "the intermediate m2m class". – Adrián May 15 '13 at 12:51
  • This is very strange. It works properly when I add a lab from the shell, but not when I add it from the Django admin interface! oO The signal is only triggered when the lab is added from the shell... Why? And how can I solve that? – user2282405 May 15 '13 at 13:25
  • @user2282405 tha'ts another question... and I'm afraid it is a bug ([ticket](https://code.djangoproject.com/ticket/16073)). – Adrián May 15 '13 at 13:34
  • Oh boy... Crap! I really need to get this working. I'm trying to solve this problem since days now! I can't change my Django version so I must find another solution. – user2282405 May 15 '13 at 13:38
  • @user2282405 My advise is to forget the m2m_changed signal and go with another method such as a save override. That bug's been open since 1.2. It would have been already fixed if it was easy. :/ – Adrián May 15 '13 at 13:45
  • The problem with the Model.save() override is that the m2m relations are not established yet, and I need them for the processing. – user2282405 May 15 '13 at 13:52
  • @user2282405 You can add lines after calling the save. I've showed you how in my answer to [this other](http://stackoverflow.com/questions/16539686/manytomanyfield-arent-available-in-the-post-save-signal) question you made. – Adrián May 15 '13 at 13:55
  • I know I can override the Model.save() method, but even, the m2m relations are totally empty un the save() method, and I need them to be full for the processing, as I said. – user2282405 May 15 '13 at 14:09
  • @user2282405 sorry I don't get what you mean. If what you need is to prepopulate the many to many then save override works, I often use it for that. Or use a [custom through model](https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.through) to represent your relationship and override its save instead. – Adrián May 15 '13 at 14:14
  • Actually I just have to access values of the ManyToMany relations, just after saving. And in the post_save signal the ManyToMany relations are still empty. That's why I've decided to use m2m_changed, because in that signal the ManyToMany relations are available. – user2282405 May 15 '13 at 14:16
  • @user2282405 the many yo many is availabe in the save method too... You just need to call super before your processing. For example I use it to maintain a particular value always in the many to many, to simplify my queries. – Adrián May 15 '13 at 14:19
  • Uh, I tried but even after calling super, my m2m relations are empty... :/ – user2282405 May 16 '13 at 06:50