[Answered ]-How add user to a group when update and create a user

1πŸ‘

βœ…

I’ll post the solution here in case anyone encounters the same problem. Along with the contribution of @mtzd. I found a tip for the solution based on the description of a problem that was in this post: https://stackoverflow.com/a/1925784/18600263. So the pos_save signal will be:

from django.db import transaction

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']


@receiver(post_save, sender=User)
def user(sender: User, instance: User, **kwargs) -> None:
    group = Group.objects.get(name=GROUPS[instance.role])
    transaction.on_commit(lambda: instance.groups.set([group], clear=True))
πŸ‘€iaggo

0πŸ‘

With your current code, when changing the user role it will be added to a new group (without being removed from the previous one). For example if the user is part of the group Staff initially and then its role changes to Company it will be added to the Company group. As the relationship between the User model and the Group model is a Many to Many relationship, the user won’t be removed from the Staff group. To do that there are to ways (which are basically the same):

First option with clear then add:

if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.clear() # Dissasociates any group the user belonged to
        instance.groups.add(group) # Adds the group

Second option with set:

if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.set([group], clear=True) # Dissasociates any group the user belonged to and sets the new group. clear=True is necessary here because otherwise the Group instances would be deleted

With all this, if you decide to go with the second option, you can go with set also for users that are being created:

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']
@receiver(post_save, sender=User)
def user(sender: User, instance: User, **kwargs) -> None:
    """
    This receiver function will set every staff pages that is created to the group staff.

    :param sender: the model that will trigger this receiver
    :param instance: the instance
    :param kwargs:
    :return: None
    """
    group = Group.objects.get(name=GROUPS[instance.role])
    instance.groups.set([group], clear=True)

and thus you don’t have to use the created param. For more info on clear and set you can read the docs https://docs.djangoproject.com/en/4.0/ref/models/relations/#django.db.models.fields.related.RelatedManager.clear and see how they can be used!

πŸ‘€mtzd

Leave a comment