Hello, I'm using Django 1.9. Trying to add a user to group on creation or save. Using either user.groups or groups.user_set.add don't work, mix and match with pre- and post-save below.
These answers aren't working for me, and so this isn't a dupe:
Adding user to group on creation in Django
Adding a user to a group in django
Add users to groups in Django
I have tried both methods in both pre- and post-save handlers.
@receiver(pre_save, sender=User)
def user_presave_handler(sender, instance, **kwargs):
if instance.is_staff and not instance.is_superuser:
# Grant all permissions
try:
instance.groups.add(Group.objects.get(name='staff_user'))
except Group.DoesNotExist:
pass
@receiver(post_save, sender=User)
def user_postsave_handler(sender, instance, **kwargs):
if instance.is_staff and not instance.is_superuser:
try:
g = Group.objects.get(name='staff_user')
except Group.DoesNotExist:
pass
else:
g.user_set.add(instance)
g.save()
You can mix and match which method is used where, I have tried it. I don't use more than one method in testing. After hitting the save button on user admin page, the user is not shown as in the group.
I double-checked that the handlers are getting called, user logic is correct, etc.
Is there something I'm doing wrong, or something that has changed in 1.9 to break the old methods?
Thanks!
Edit: For those asking, the group is created like this:
group, __ = Group.objects.get_or_create(name='staff_user')
permissions = Permission.objects.all()
for p in permissions:
group.permissions.add(p)
group.save()
I have debugged it and the group definitely exists, though maybe I made it wrong and so it won't be applied?
I think it's related to this: Issue with ManyToMany Relationships not updating inmediatly after save . Somethere reports in a comment that it's still current in 1.10.
The problem is that you can also select groups on the admin 'add user' page; and then when you save the User, the following happens:
You can use a m2m_changed signal, apparently. I've never used it, but I think something like this should work:
from django.db.signals import m2m_changed
@receiver(m2m_changed, sender=User.groups.through)
def user_groups_changed_handler(sender, instance, action, **kwargs):
if action == 'post_add' and instance.is_staff and not instance.is_superuser:
if not instance.groups.filter(name='staff_user').exists():
try:
g = Group.objects.get(name='staff_user')
except Group.DoesNotExist:
pass
else:
instance.groups.add(g)
This is assuming the instance
that the signal receives is a User, otherwise it's going to look slightly different. The check for the action and the check whether the group was already added are to prevent infinite loops. The sender is the hidden 'through' table for the many to many relation, User.groups.through
.
Python 3, Django==2.1.7
def add_user_to_group(sender, instance: User, created: bool, **kwargs):
try:
if created:
group = Group.objects.get(name=instance.user_type)
instance.groups.add(group)
instance.save()
except Group.DoesNotExist:
pass
models.signals.post_save.connect(add_user_to_group, sender=User)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With