trigger - señales django
Identificar los campos modificados en la señal django post_save (2)
Estoy usando la señal post_save de django para ejecutar algunas declaraciones después de guardar el modelo.
class Mode(models.Model):
name = models.CharField(max_length=5)
mode = models.BooleanField()
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Mode)
def post_save(sender, instance, created, **kwargs):
# do some stuff
pass
Ahora quiero ejecutar una declaración basada en si el valor del campo de mode
ha cambiado o no.
@receiver(post_save, sender=Mode)
def post_save(sender, instance, created, **kwargs):
# if value of `mode` has changed:
# then do this
# else:
# do that
pass
Miré algunos hilos SOF y un blog, pero no pude encontrar una solución para esto. Todos ellos intentaban usar el método o formulario pre_save que no son mi caso de uso. https://docs.djangoproject.com/es/1.9/ref/signals/#post-save en los documentos de django no menciona una forma directa de hacer esto.
Una respuesta en el enlace de abajo parece prometedora, pero no sé cómo usarla. No estoy seguro de si la última versión de django lo admite o no, porque utilicé ipdb
para depurar esto y encontré que la variable de instance
no tiene ningún atributo ha has_changed
como se menciona en la siguiente respuesta.
Django: Al guardar, ¿cómo puedes verificar si un campo ha cambiado?
Usualmente, es mejor anular el método de guardado que usar señales.
De Dos medidas de django : "Use las señales como último recurso".
Estoy de acuerdo con la respuesta de @scoopseven sobre el almacenamiento en caché del valor original en el init, pero invalidar el método de guardado si es posible.
class Mode(models.Model):
name = models.CharField(max_length=5)
mode = models.BooleanField()
__original_mode = None
def __init__(self, *args, **kwargs):
super(Mode, self).__init__(*args, **kwargs)
self.__original_mode = self.mode
def save(self, force_insert=False, force_update=False, *args, **kwargs):
if self.mode != self.__original_mode:
# then do this
else:
# do that
super(Mode, self).save(force_insert, force_update, *args, **kwargs)
self.__original_mode = self.mode
__init__
en el __init__
de tu modelo para que tengas acceso a él.
def __init__(self, *args, **kwargs):
super(YourModel, self).__init__(*args, **kwargs)
self.__original_mode = self.mode
Ahora puedes realizar algo como:
if instance.mode != instance.__original_mode:
# do something useful