Skip to content

Instantly share code, notes, and snippets.

@gterzian
Created September 6, 2013 10:52
Show Gist options
  • Save gterzian/6462324 to your computer and use it in GitHub Desktop.
Save gterzian/6462324 to your computer and use it in GitHub Desktop.
Django Recipes: Manipulating a model’s m2m from within a signal handler
from django.db.models.signals import pre_save, post_save, m2m_changed
def save_handler(sender, instance, *args, **kwargs):
m2m_changed.connect(m2m_handler, sender=sender.m2mfield.through, weak=False)
def m2m_handler(sender, instance, action, *args, **kwargs):
if action =='post_clear':
succesfully_manipulate_m2m(instance)
pre_save.connect(save_handler, sender=YouModel, weak=False)
@gterzian
Copy link
Author

gterzian commented Sep 6, 2013

problem:
When you manipulate the m2m of a model within a post or pre_save signal receiver, your changes get wiped out in the subsequent ‘clearing’ of the m2m by Django.

solution:
In you post or pre_save signal handler, register another handler to the m2m_changed signal on the m2m intermediary model of the model whose m2m you want to update.

Please note that this second handler will receive several m2m_changed signals, and it is key to test for the value of the ‘action’ arguments passed along with them.

Within this second handler, check for the ‘post_clear’ action. When you receive a signal with the post_clear action, the m2m has been cleared by Django and you have a chance to successfully manipulate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment