Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Django, how do I get a signal for when a Group has a User added or removed?

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.

like image 521
fastmultiplication Avatar asked Oct 26 '11 05:10

fastmultiplication


1 Answers

From the django doc:

sender - The intermediate model class describing the ManyToManyField. This class is automatically created when a many-to-many field is defined; you can access it using the through attribute on the many-to-many field.

When subscribing to m2m_changed like so:

@receiver(m2m_changed)
def my_receiver(**kwargs):
    from pprint import pprint
    pprint(kwargs)

You will receive a bunch of signals like this (shortened):

{'sender': <class 'django.contrib.auth.models.User_groups'>,
 'action': 'post_add',
 'instance': <User: bouke>,
 'model': <class 'django.contrib.auth.models.Group'>,
 'pk_set': set([1]),
 'reverse': False,
 'signal': <django.dispatch.dispatcher.Signal object at 0x101840210>,
 'using': 'default'}

So the user bouke has been added to pk_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 are pre_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 and instance) when editing a group instead of a user.

like image 109
Bouke Avatar answered Oct 13 '22 19:10

Bouke