11

en cuenta lo siguiente:Django señal post_save envía formsets línea obsoletas

class OrderForm(models.Model): 
    title = models.CharField(max_length=100) 
    desc = models.TextField() 


class OrderFormLine(models.Model): 
    order = models.ForeignKey(OrderForm) 
    lagel = models.CharField(max_length=100) 
    qty = models.IntegerField(...) 
    price = models.FloatField(...) 

Ahora quiero enviar un correo electrónico con los detalles OrderForm cada vez que alguien crea uno o modificar uno.

Sin ciencia espacial hasta ahora ... usemos solo una señal de post_save;

post_save.connect(email_notify, sender=OrderForm) 

Pero hay un pequeño problema, el objeto OrderForm pasado a email_notify se actualiza con los nuevos datos como se esperaba, pero no los elementos OrderFormLine relacionados.

He intentado anular los métodos guardados en el administrador Y en el modelo, he intentado guardar el objeto, el formulario y su relación antes de pasarlo a mi controlador de notificaciones, nada funciona.

Soy consciente de que podría adjuntar la señal post_save al modelo OrderItem, pero luego se enviaría el correo electrónico para cada elemento.

Ayuda Estoy al borde de la locura.

ACTUALIZACIÓN:

Found a simple and reliable solution

historia corta:

def email_notify_orderform(sender, **kwargs): 
    instance = kwargs['instance'] 
    ct = ContentType.objects.get_for_model(OrderForm) 
    if ct.id == instance.content_type.id: 
     print instance.is_addition() 
     print instance.is_change() 
     print instance.is_deletion() 
     print instance.change_message 
     print instance.action_time 
     print instance.get_edited_object().total() # BINGO ! 
post_save.connect(email_notify_orderform, sender=LogEntry) 
+1

Debe guardar el formulario de pedido para tener un número de ID válido para asociar con sus líneas de pedido. Me parece que una señal personalizada está en orden; eso podría salvarte de tu locura. A veces, los casos especiales no son malvados, y este es un caso especial muy pequeño. "OrderForm" señala cuando está completamente instanciado, y su oyente espera eso en lugar de post_save. –

+0

Nunca escuché sobre escribir señales personalizadas ... y no puedo encontrar mucho sobre este tema. Por lo que entiendo, las señales están estrechamente conectadas en django y no existe un mecanismo para proporcionar señales personalizadas. Está documentado? –

+0

no importa, encontró el documento –

Respuesta

6

El problema básico es que cuando los principales objetos son enviados post_save señal, los inlines no se han guardado todavía: la el modelo padre siempre se guarda primero. Entonces, no es que esté enviando datos viejos; de hecho, es el estado actual de los datos.

La solución más simple es crear una señal personalizada y enviar esa señal a un lugar donde se guardaron las líneas. El método save_formset en ModelAdmin es su gancho.

+0

A menos que haya algo que no entienda acerca de su respuesta, no funciona. Puedes ver en la publicación del blog todos los métodos que he probado, incluido el uso de save_formset: http://haineault.com/blog/141/ –

+0

@ h3 ¿Ya entendiste la idea? Ha pasado mucho tiempo pero puedes consultar esta [publicación] (http: // stackoverflow.com/questions/14858559/save-the-related-objects-before-the-real-object-being-edited-on-django-admin) y sus soluciones que ilustran el uso de [save_formset] (https: // docs. djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_formset). Dejé el comentario en caso de que alguien se topa con esta publicación – raratiru

Cuestiones relacionadas