Question

Im trying to connect a "Information" object to many "Customers" (see code below)

When one Information object is updated, I want to send email to each Customer that is connected to the Information.

However, when I log the sold_to field that the signal recieves I always get what the data is like BEFORE the save.

I'm guessing this is because its ManyToManyField and the data is stored in a separate table, but shouldn't the post_save signal be called after all relations have been updated?

Anyone got a suggestion for a solution?

class Customer
    name = models.CharField(max_length=200)
    category = models.ManyToManyField('Category',symmetrical=False)
    contact = models.EmailField()

class Information
    name = models.CharField(max_length=200)
    email = models.EmailField(max_length=200)
    mod_date = models.DateTimeField(auto_now=True)
    sold_to = models.ManyToManyField(Customer, null=True, blank=True)


def send_admin_email(sender, instance, signal, *args, **kwargs):
    from myapp import settings
    for cust in instance.sold_to.all():
        settings.debug(cust.name)

post_save.connect(send_admin_email, sender=Information)

Edit: apollo13 in #django alerted me to this: "Related items (the things being saved into the many-to-many relation) are not saved as part of a model's save method, as you have discovered." - http://groups.google.com/group/django-users/msg/2b734c153537f970

But since its from Jul 9 2006 I really really hope there is a solution for this.

Was it helpful?

Solution

There's an open ticket for the issue you are facing here. You could either keep an eye on that for when it makes it into a release, or you could try applying the patch that it provides and see if that helps.

OTHER TIPS

This is my solution, after applying the patch from code.djangoproject.com mentioned above.

Added this in models.py:

from django.db.models.signals import m2m_changed
m2m_changed.connect(send_admin_email, sender=Information)

And the send_admin_email function:

def send_customer_email(sender, instance, action, model, field_name, reverse, objects, **kwargs):
    if ("add" == action):
        # do stuff

I run across the same issue since I have M2M fields in my model I also got the pre_save like data.

In the situation, the problem is that in M2M fields both related models should be saved in order to get the auto generated IDs.

In my solution, neither I used the post_save signal nor m2m_changed signal, instead of that signals I used log_addition and log_change methods in ModelAdmin class definition.

In your custom ModelAdmin class:

    class CustomModelAdmin(admin.ModelAdmin):
         def log_addition(self, request, object):
         """
         Log that an object has been successfully added.
         """
             super(CustomModelAdmin, self).log_addition(request, object)
             #call post_save callback here object created

         def log_change(self, request, object):
         """
         Log that an object has been successfully changed.
         """
             super(CustomModelAdmin, self).log_change(request, object)
             #call post_save callback here object changed

If you want, you may also override log_deletion() method.

Happy overriding...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top