Skip to content

signals

django_spire.history.activity.signals

ACTIVITY_M2M_ACTIONS_HANDLED = frozenset({ActivityM2mAction.POST_ADD, ActivityM2mAction.POST_CLEAR, ActivityM2mAction.POST_REMOVE, ActivityM2mAction.PRE_CLEAR, ActivityM2mAction.PRE_REMOVE}) module-attribute

ACTIVITY_M2M_CLEARED_STATE_ATTRIBUTE = '_activity_m2m_cleared_state' module-attribute

ACTIVITY_M2M_NAMED_COUNT_MAX = 10 module-attribute

ACTIVITY_M2M_PRESENT_PK_SET_ATTRIBUTE = '_activity_m2m_present_pk_set' module-attribute

connect_activity_signals

Source code in django_spire/history/activity/signals.py
def connect_activity_signals() -> None:
    for model in apps.get_models():
        if not issubclass(model, ActivityMixin):
            continue

        label = model._meta.label_lower

        post_save.connect(
            create_activity_on_save,
            sender=model,
            dispatch_uid=f'django_spire_activity_post_save.{label}',
        )

        post_delete.connect(
            create_activity_on_delete,
            sender=model,
            dispatch_uid=f'django_spire_activity_post_delete.{label}',
        )

        for field in model._meta.many_to_many:
            _connect_m2m(field.remote_field.through)

        for relation in model._meta.related_objects:
            if relation.many_to_many:
                _connect_m2m(relation.through)

create_activity_on_delete

Source code in django_spire/history/activity/signals.py
def create_activity_on_delete(
    sender: type[models.Model],
    instance: models.Model,
    **kwargs
) -> None:
    _ = sender
    _ = kwargs

    if not isinstance(instance, ActivityMixin):
        return

    user = get_current_user()

    if not user:
        return

    if _is_same_row(instance, user):
        return

    entries = get_delete_activity_entries()

    if entries is not None:
        entry = (
            instance._meta.concrete_model,
            instance.pk,
            build_activity_information(instance, user, ActivityVerb.DELETED),
        )

        entries.append(entry)

        return

    add_activity(instance, user, ActivityVerb.DELETED)

create_activity_on_m2m_change

Source code in django_spire/history/activity/signals.py
def create_activity_on_m2m_change(
    sender: type[models.Model],
    instance: models.Model,
    action: str,
    model: type[models.Model],
    pk_set: set | None,
    *,
    reverse: bool = False,
    **kwargs
) -> None:
    _ = kwargs

    if action not in ACTIVITY_M2M_ACTIONS_HANDLED:
        return

    if not isinstance(instance, ActivityMixin):
        return

    user = get_current_user()

    if not user:
        return

    if action == ActivityM2mAction.PRE_CLEAR:
        cleared_state = _m2m_cleared_state(sender, instance, model, reverse)
        instance.__dict__[ACTIVITY_M2M_CLEARED_STATE_ATTRIBUTE] = cleared_state
        return

    if action == ActivityM2mAction.PRE_REMOVE:
        present_pk_set = _m2m_present_pk_set(sender, instance, model, pk_set, reverse)
        instance.__dict__[ACTIVITY_M2M_PRESENT_PK_SET_ATTRIBUTE] = present_pk_set
        return

    count, named_pks = _m2m_change_state(action, instance, pk_set)

    if count == 0:
        return

    if action == ActivityM2mAction.POST_ADD:
        verb = ActivityVerb.ADDED
        preposition = 'to'
    else:
        verb = ActivityVerb.REMOVED
        preposition = 'from'

    related_name = (
        model._meta.verbose_name
        if count == 1
        else model._meta.verbose_name_plural
    )

    names = _m2m_related_names(model, named_pks)

    information = _m2m_information(
        user=user,
        verb=verb,
        count=count,
        related_name=related_name,
        preposition=preposition,
        instance=instance,
        names=names,
    )

    instance.add_activity(user=user, verb=verb, information=information)

create_activity_on_save

Source code in django_spire/history/activity/signals.py
def create_activity_on_save(
    sender: type[models.Model],
    instance: models.Model,
    created: bool,
    raw: bool = False,
    **kwargs
) -> None:
    _ = sender
    _ = kwargs

    if not isinstance(instance, ActivityMixin):
        return

    verb_override = instance.__dict__.pop(ACTIVITY_VERB_ATTRIBUTE, None)

    if raw:
        return

    user = get_current_user()

    if not user:
        return

    if verb_override is not None:
        verb = verb_override
    elif created:
        verb = ActivityVerb.CREATED
    else:
        verb = ActivityVerb.UPDATED

    add_activity(instance, user, verb)