Mohiuddin Sumon
Mohiuddin Sumon

Reputation: 153

Django Admin - change user type (is_staff = T/F) based on group assignment

I have a django app with 3 types of user, super_user, admin, user. From django-admin panel I am assigning a user to Admin group. Admin group is a group with allowed permission. So when I am assigning a user I am changing their is_staff to True in GroupAdminForm. Problem is when I remove a user from the group I can not change those users is_staff to false. Here's my GroupAdminForm

Also I see that save_m2m is being called 2 times, but I am calling it once. what is the flow of saving here ?

class GroupAdminForm(forms.ModelForm):
    class Meta:
        model = Group
        exclude = []

    users = forms.ModelMultipleChoiceField(
         queryset=User.objects.all(),
         required=False,
         widget=FilteredSelectMultiple('users', False)
    )

    def __init__(self, *args, **kwargs):
        super(GroupAdminForm, self).__init__(*args, **kwargs)
        old_users = None
        if self.instance.pk:
            self.fields['users'].initial = self.instance.user_set.all()
            old_users = self.instance.user_set.all()

    def save_m2m(self):
        print(f'Users = ', self.instance.user_set.all())
        print(f'M2M Called - {self.test}')
        self.instance.user_set.set(self.cleaned_data['users'])

    def save(self, *args, **kwargs):
        instance = super(GroupAdminForm, self).save()
        all_users = self.instance.user_set.all()
        print('Save Called')

        self.save_m2m()

        users = self.cleaned_data['users']
        if instance.name == 'Admin':
            for user in users:
                user.is_staff = True
                user.save()


        return instance


Upvotes: 0

Views: 802

Answers (1)

Messaoud Zahi
Messaoud Zahi

Reputation: 1232

save_m2m is being called 2 times

save() method accepts an optional commit keyword argument, which accepts either True or False (default is True). If you call save() with commit=True, your case here:

instance = super(GroupAdminForm, self).save()

Django will call save_m2m() automatically. Documentation To prevent that use commit=False

 instance = super(GroupAdminForm, self).save(commit=False)

Problem is when I remove a user from the group I can not change those users is_staff to false

Use m2m_changed signal to update the is_staff attribute

Upvotes: 1

Related Questions