python - signal - La señal de post_save no se llama
receiver signal django (3)
¿Estás seguro de que las signals
correctas se importan? ( print(''hi, signals here'')
en el módulo?)
Es posible que desee utilizar una importación absolutamente calificada ( import orders.signals
) o una relativa ( import .signals as signals
), también.
Ya leí todas las preguntas relacionadas.
Tengo dos proyectos de Django, y las señales funcionan bien en uno, pero no funcionan en el segundo (simplemente copié el código y cambié los nombres respectivamente).
Tengo una aplicación de pedidos con el modelo de pedido. La aplicación está incluida en la configuración INSTALLED_APPS.
Tengo la configuración de la aplicación en apps.py:
from django.apps import AppConfig
class OrdersConfig(AppConfig):
name = ''orders''
def ready(self):
super(OrdersConfig, self).ready()
# noinspection PyUnresolvedReferences
import signals
__init__.py
:
default_app_config = ''orders.apps.OrdersConfig''
Y, finalmente, signals.py:
@receiver(post_save, sender=Order)
def order_save(sender, instance, created, **kwargs):
print ''Post save''
if created:
print ''Created''
send_email_new_order.delay(settings.MODERATOR_EMAIL, instance.pk)
Y la señal no se llama. ¿Por qué?
Django 1.10.3.
¿Tienes otra aplicación también llamada signals
?
Pruebe la importación relativa en el método ready
: from . import signals
from . import signals
¿Cuándo se lanzaría post_save?
Lo que dice el documento: Al final del método de guardar.
Lo que realmente significa: al final de la finalización exitosa del método de guardar.
¿Cuándo no se disparará la señal?
- Si el método
save
no guarda correctamente el objeto (como cuando se produce unIntegrityError
) - Cuando llama a
MyModel.objects.update()
- Cuando anula el método de
save
y olvida llamar al método de la superclase. - Cuando su receptor de señal no se ha registrado correctamente.
Cómo registrar el receptor
Lo más simple es usar el decorador @receiver
como lo ha hecho. La alternativa es usar
from django.db.models.signals import pre_save
pre_save.connect(order_save, sender=''app_label.MyModel'')
¿Dónde debe colocarse este código?
Hoy en día, el manual establece que
Estrictamente hablando, el código de manejo y registro de señales puede vivir en cualquier lugar que desee, aunque se recomienda evitar el módulo raíz de la aplicación y su módulo de modelos para minimizar los efectos secundarios de la importación de código.
Esa es probablemente la razón por la que en este caso usted ha creado un archivo llamado signals.py y coloca su código dentro de eso y ha tenido todos los problemas con la clase AppConfig y el método listo. Pero, curiosamente, el manual de Django 1.6 dice:
Puede poner el código de manejo y registro de señal en cualquier lugar que desee. Sin embargo, deberá asegurarse de que el módulo en el que se encuentra se importe desde el principio para que el manejo de la señal se registre antes de enviar señales. Esto hace que models.py de su aplicación sea un buen lugar para colocar el registro de manejadores de señal.
Por lo tanto, si tiene problemas para registrar su receptor de señal, puede intentar poner el código en models.py
o views.py
y omitir los bits de AppConfig (incluso eliminar AppConfig por completo).
Si desea realizar el registro en AppConfig y tiene problemas con @reciever
y / o las importaciones, puede intentarlo
from django.db.models.signals import pre_save
from app_label.signals import my_reciever
def ready(self):
pre_save.connect(my_reciever, sender=''app_label.MyModel'')
¿Cómo evitar las repeticiones?
¿La señal se dispara dos veces? Asegúrese de registrar el receptor solo una vez. Si lo registra en AppConfig
, déjelo fuera de models.py
y vice verce