Home > Software design >  Django `sender` not working for signal receiver
Django `sender` not working for signal receiver

Time:09-23

I am trying to create a post_save handler for when the model Client has been saved. The reason I am using a signal is because I require for the code run when a Client is added via loaddata as well.

Heres the sender:

# apps.py
from django.db.models.signals import post_save


class ClientsConfig(AppConfig):
    name = 'clients'
    verbose_name = "clients"

    def ready(self):
        """https://docs.djangoproject.com/en/4.1/topics/signals/"""
        # Implicitly connect signal handlers decorated with @receiver.
        from . import signals
        # Explicitly connect a signal handler.
        post_save.connect(signals.write_svg, dispatch_uid="clients_client_post_save")

Heres the receiver:

# signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver

from .models import Client


@receiver(post_save, sender=Client)
def write_svg(sender, instance, **kwargs):
    """Using a signal so that when one loaddata the DB, it performs this action too"""
    print('\n-----------------------------------------------------')
    print('Signal called, sender', sender)

Here you can see it prints for a whole bunch of Session events, and many other events, instead of being filtered for only the client model:

-----------------------------------------------------
Signal called, sender <class 'django.contrib.sessions.models.Session'>

-----------------------------------------------------
Signal called, sender <class 'django.contrib.sessions.models.Session'>

-----------------------------------------------------
Signal called, sender <class 'django.contrib.sessions.models.Session'>

-----------------------------------------------------
Signal called, sender <class 'django.contrib.sessions.models.Session'>

-----------------------------------------------------
Signal called, sender <class 'django.contrib.sessions.models.Session'>

CodePudding user response:

You have to remove the

post_save.connect(signals.write_svg, dispatch_uid="clients_client_post_save")

You have already used the receivers decorator, you do not need to use the connect function too.

The first comment on your ready method explains this behaviour ;)

CodePudding user response:

The issue is the signal was being registered twice. If you use the @receiver decorator, the line:

from . import signals

Will automatically connect the signal, you don't need to explicitly register it. The second time it was registered was with the line:

post_save.connect(signals.write_svg, dispatch_uid="clients_client_post_save")

Which does not have the sender filter.

  • Related