Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ManyToManyField is empty in post_save() function

Tags:

python

django

When a new record is added to a table, I have to execute a SQL statement on an external database. This query includes the use of a ManyToManyField. So I just connected the function like this:

post_save.connect(post_save_mymodel, sender=MyModel)

And in my post_save_mymodel() function, here is what I do:

def post_save_mymodel(sender, instance, created, *args, **kwargs):
    if created:
        for e in instance.my_m2mfield.all():
            # Query including "e".

But, too bad, instance.my_m2mfield.all() is always empty! Even though they should contain some elements! I tried to get the new element by doing

new_element = MyModel.objects.get(pk=instance.pk)

but it doesn't change anything, I've still got the same issue...

Wny help/advice?

like image 536
Deneuve Avatar asked Apr 09 '13 09:04

Deneuve


1 Answers

This is because you first save your instance and after that you add m2m relations to it. This is how ManyToMany fields work in Django data models. Django needs to know the ID of the items that should be connected with m2m relations.

I think that your code looks like this:

instance = MyModel.objects.create(some_field=some_value)  # post save signal triggered here
instance.my_m2mfield = my_set_of_m2m_models

You need to connect your handler to the django.db.models.signals.m2m_changed signal. See the docs. For example:

def post_save_mymodel(sender, instance, action, reverse, *args, **kwargs):
    if action == 'post_add' and not reverse:
        for e in instance.my_m2mfield.all():
            # Query including "e"
m2m_changed.connect(post_save_mymodel, sender=MyModel.my_m2mfield.through)
like image 53
Igor Avatar answered Sep 28 '22 04:09

Igor