Django accessing ManyToMany fields from post_save signal
You're not going to. M2Ms are saved after instances are saved and thus there won't be any record at all of the m2m updates. Further issues (even if you solve that) are that you're still in a transaction and querying the DB won't get you m2m with proper states anyways.
The solution is to hook into the m2m_changed
signal instead of post_save
.
https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed
Your sender then would be Project.assigned_to.through
If your m2m can be empty (blank=True
) you are in a little trouble with m2m_changed
, because m2m_changed
doesn't fire if m2m wasn't set. You can solve this issue by using post_save
and m2m_changed
at the same time. But there is one big disadvantage with this method - your code will be executed twice if m2m field isn't empty.
So, you can use transaction's on_commit (Django 1.9+)
Django provides the
on_commit()
function to register callback functions that should be executed after a transaction is successfully committed.
from django.db import transaction
def on_transaction_commit(func):
def inner(*args, **kwargs):
transaction.on_commit(lambda: func(*args, **kwargs))
return inner
@receiver(post_save, sender=SomeModel)
@on_transaction_commit
def my_ultimate_func(sender, **kwargs):
# Do things here
Important note: this approach works only if your code calls save()
.
post_save
signal doesn't fire at all in cases when you call only instance.m2m.add()
or instance.m2m.set()
.