2011-04-15 12 views
5

Necesito enviar un correo electrónico cuando se crea una nueva instancia del modelo Entry a través del panel de administración. Así que en models.py tengo:Acceso a datos relacionados de la instancia del modelo recién creado usando el manejador de señal post_save

class Entry(models.Model): 
    attachments = models.ManyToManyField(to=Attachment, blank=True) 
    #some other fields 
    #... 
    sent = models.BooleanField(editable=False, default=False) 

Entonces estoy registring función de controlador post_save:

def send_message(sender, instance, **kwargs): 
    if not instance.sent: 
     #sending an e-mail message containing details about related attachments 
     #... 
     instance.sent = True 
     instance.save() 

post_save.connect(send_message, sender=Entry) 

Funciona, pero como he mencionado antes, también necesito para tener acceso a los archivos adjuntos relacionados para incluir sus datos en el mensaje. Desafortunadamente, instance.attachments.all() devuelve la lista vacía dentro de la función send_message, incluso si los archivos adjuntos realmente se han agregado.

Como me di cuenta, cuando se envía la señal post_save, los datos relacionados del modelo guardado no se guardan aún, por lo que no puedo obtener archivos adjuntos relacionados desde ese lugar. La pregunta es: ¿puedo lograr esto usando señales, o de cualquier otra manera, o tengo que poner este código de envío de correo electrónico afuera, por ejemplo anulando la vista de cambio del panel de administración para el modelo Entry?

Respuesta

1

Debería poder hacer esto anulando el método save_model() en el ModelAdmin. Puede enviar su correo electrónico allí o disparar una señal personalizada que activa su controlador para enviar el correo electrónico.

Si tiene líneas, creo que necesita usar save_formset() en su lugar.

+0

Gracias. Eso debería ser lo que necesito. Trataré de hacerlo de esta manera. – Dzejkob

2

¿Quizás podría usar el M2M Changed Signal en su lugar? Esta señal se envía cuando se cambia el campo M2M.

+0

Sí estaba pensando en ella. Pero, ¿cómo exactamente podría ser utilizado? Como puede ver, el campo de archivos adjuntos tiene en blanco = Verdadero, por lo que puede haber una situación, cuando no hay ningún archivo adjunto relacionado, y como supongo, no se enviará ninguna señal de m2m_changed. Y si conecto la señal m2m_changed a mi controlador send_message, y habrá más de un archivo adjunto agregado, el mensaje de correo electrónico será (como creo) enviado varias veces, lo cual también es incorrecto. Entonces, ¿alguna idea de resolver esto? – Dzejkob

+0

Dudo que esto se pueda hacer con señales. Tendrás que hacer esto con una aplicación Django personalizada (no con el administrador incorporado). Es mucho trabajo, pero no veo una forma de evitarlo. Básicamente 1) envíe el formulario 2) cree un objeto + relaciones en función de lo que se ingresó y 3) si es exitoso, envíe un correo electrónico. –

1

Intenté utilizar ModelAdminsave_model() método, como se propuso shadfc. De todos modos, los objetos relacionados recientemente cambiados no son accesibles desde allí. Pero save_model toma el form como parámetro, así que lo usé. Mi send_message ya no se usa como manejador de señal y agregué el parámetro related_data.

def send_message(sender, instance, related_data={}): 
    #sending e-mail using related_data parameter to access additional related objects 
    #... 

en admin.py que tengo:

class EntryAdmin(admin.ModelAdmin): 
    def save_model(self, request, obj, form, change): 
     obj.save() 
     send_message(sender=Entry, instance=obj, 
        related_data={'attachments': form.cleaned_data['attachments']}) 
Cuestiones relacionadas