2009-08-03 17 views
9

Im tratando de conectar un objeto de "Información" a muchos "Clientes" (ver código a continuación)¿Por qué Django post_save signal me da datos pre_save?

Cuando se actualiza un objeto de información, quiero enviar un correo electrónico a cada cliente que está conectado a la información.

Sin embargo, cuando registro el campo sold_to que la señal recibe, siempre obtengo los datos antes de guardarlos.

Supongo que esto se debe a que ManyToManyField y los datos se almacenan en una tabla separada, pero ¿no debería invocarse la señal post_save después de que se hayan actualizado todas las relaciones?

¿Alguien tiene una sugerencia para una solución?

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) 

Editar: Apollo13 en #django me alertó a esto: "artículos relacionados (las cosas que se guardan en la relación de muchos a muchos) no se guardan como parte de un modelo de guardar el método, como se haber descubierto." - http://groups.google.com/group/django-users/msg/2b734c153537f970

Pero desde su 9 de julio de 2006 realmente espero que haya una solución para esto.

Respuesta

5

Hay un boleto abierto para el problema al que se enfrenta here. Podrías vigilar eso para cuando se convierta en un lanzamiento, o podrías intentar aplicar el parche que proporciona y ver si eso te ayuda.

+0

Gracias por la rápida respuesta. Probé el parche, y después de un poco de piratería lo hice funcionar. Publicaremos la solución a continuación. – schmilblick

1

Esta es mi solución, después de aplicar el parche de code.djangoproject.com mencionado anteriormente.

Agregado esto en models.py:

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

Y la función send_admin_email:

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

me encuentro con el mismo problema ya que tengo campos M2M en mi modelo que también tuvo la pre_save como datos.

En esta situación, el problema es que en los campos M2M ambos modelos relacionados deben guardarse para obtener los ID generados automáticamente.

En mi solución, ni utilicé la señal post_save ni la señal m2m_changed, en lugar de esas señales utilicé los métodos log_addition y log_change en la definición de clase ModelAdmin.

En su clase de ModelAdmin personalizado:

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 

Si lo desea, puede también log_deletion método() anular.

primordial feliz ...

Cuestiones relacionadas