[Django]-Dynamically adding many to many relationships in the save method in Django

5👍

You can’t work on an m2m relationship in a custom save method because of the way Django writes those relationships to the database. When saving a model instance with an m2m relationship, Django first writes the object then goes in again and writes the appropriate m2m relationships. Since the m2m stuff comes “second,” trying to work with the relationship in a custom save fails.

The solution is to use a post-save signal. Remove the custom save stuff and add this below your model definitions, making sure to import receiver and post_save:

@receiver(post_save, sender = Content)
def update_m2m_relationships_on_save(sender, **kwargs):
    if not kwargs['instance'].is_tagged:
        tag_content(kwargs['instance'].pk)

Your tag_content function should probably swap is_tagged to True and then save the instance; if that boolean is never flipped then this could just run in an endless loop. You can also just pass in the object instead of passing in the pk:

def tag_content(thing_to_tag):
    thing_to_tag.tags.add([1,2,3])
    thing_to_tag.is_tagged = True
    thing_to_tag.save()
    return thing_to_tag

Note the use of .add(), which is important when adding to an m2m relationship.

Leave a comment