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)