Django Signals Inheriting Signals on Extended Models

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Extensions
> Step 2: And Like the video. BONUS: You can also share it!

Example

Django's signals are restricted to precise class signatures upon registration, and thus subclassed models are not immediately registered onto the same signal.

Take this model and signal for example

class Event(models.Model):
    user = models.ForeignKey(User)


class StatusChange(Event):
    ...


class Comment(Event):
    ...


def send_activity_notification(sender, instance: Event, raw: bool, **kwargs):
    """
    Fire a notification upon saving an event
    """

    if not raw:
        msg_factory = MessageFactory(instance.id)
        msg_factory.on_activity(str(instance))
post_save.connect(send_activity_notification, Event)

With extended models, you must manually attach the signal onto each subclass else they won't be effected.

post_save.connect(send_activity_notification, StatusChange)
post_save.connect(send_activity_notification, Comment)

With Python 3.6, you can leverage some additional class methods build into classes to automate this binding.

class Event(models.Model):

    @classmethod
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        post_save.connect(send_activity_notification, cls)


Got any Django Question?