0

I have a problem with duplicate signals. I have looked-up the relevant part of Django docs and a similar question on Stackoverflow but I still can't get it working right - i.e. the action that I have planned (creation on an ActivityLog entry) is actually happening 4 times :/

I have added the dispatch_uid and the problem still persists, so I guess I'm doing something wrong. Can you please hint me to the error?

Here's my code:

signals.py

from patient.models import Patient
from .models import ActivityLog

@receiver(pre_save, sender=Patient)
def create_new_patient(sender, instance, **kwargs):


    ActivityLog.objects.create(
        user=instance.created_by_user,
        event='created a new patient',
        patient_id=instance.patient_id
    )

and this is it's usage in the patient.apps module:

from django.apps import AppConfig
from django.db.models.signals import pre_save

app_name = "patient"


class PatientConfig(AppConfig):
    name = 'patient'
    verbose_name = "Patients"

    def ready(self):
        from activity_logger.signals import create_new_patient
        print('Patient APP is ready!')
        pre_save.connect(create_new_patient, sender='patient.Patient', dispatch_uid='patient')

The print Patient APP is ready! does appear twice, and the object gets created 4 times, despite setting the dispatch_uid. What have I misunderstood?

user1544500
  • 2,067
  • 5
  • 25
  • 35

1 Answers1

1

The @receiver(Signal,...) decorator is a shortcut for Signal.connect(...), so you indeed register your create_new_patient handler twice (once thru @receiver when importing your signals module, the second time with pre_save.connect().

Solution : in your App.ready() method, you should just import your app's signal.py module. This will trigger the registration of the handlers decorated with @receiver.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • Hi, @bruno desthuilliers great answer! Indeed - that reduced the numer of created ActivityLogs objects to ... just 2 (previously 4). The reason is that the ready() function is triggered twice (e.g. the 'Patient APP is ready' appears twice). Any idea why ? – user1544500 Jun 04 '18 at 11:23
  • @user1544500 Nope, and I'd like to know how you managed to get this happening actually . Hint: add a debugger breakpoint in your `App.ready` method and inspect the call stack in the first and second call. – bruno desthuilliers Jun 04 '18 at 11:51