In the Django admin I sometimes add or delete users to or from (existing) groups. When this happens I'd like to be able to run a function.
I'm just using the standard User and Group models.
I have looked at doing it with signals, through m2m_changed, but it seems to need a Through class - and I don't think there is one in this case.
From the django doc:
When subscribing to m2m_changed like so:
You will receive a bunch of signals like this (shortened):
So the user
bouke
has been added topk_set
groups:[1]
. However I noted that the admin layout clears all groups and then adds the selected groups back in. The signals you will receive arepre_clear
,post_clear
,pre_add
,post_add
. Using a combination of these signals you could store the pre and post groups. Doing a diff over these lists, you have the deleted and added groups for the user.Note that the signals are the other way around (
pk_set
andinstance
) when editing a group instead of a user.You'll see in the Django documentation (v1.11) that your desired sender should be the intermediate
through
field belonging to theManyToMany
field, wherever that's defined. If you register that as your sender, then you'll be listening to eg Users adding Groups to themselves, as well as Groups adding Users to themselves.You need to create a signal using
m2m_changed
as a receiver. According to the official Django documentation:So, the simplest implementation is as follows:
In your case, you want to perform something when a user is added or removed from a group, so you can take advantage of the
action
parameter when it takes the values'pre_add'
,'post_add'
,'pre_remove'
, and'post_remove'
. You can also take advantage ofpk_set
parameter which contains primary key values that have been added to or removed from the relation.It might be better to try and achieve this with
django-celery
, that way you can write custom tasks, and based on a certain criteria (such as removal or addition) you can fire of a certain task.