[Answered ]-Django check user groups in forms

1👍

Are you using class based views?

If so, in the corresponding view add:

def get_form_kwargs(self):
    kwargs = super(GwagenView, self).get_form_kwargs()  # change to view name

    return dict(kwargs, groups=self.request.user.groups.values_list('name', flat=True))

then change the init of the form to:

def __init__(self, groups, *args, **kwargs):
    super(gwagen1Form, self).__init__(*args, **kwargs)
    self.fields["verk_num"].initial = benutzer.objects.get(flag_default=True)

    if groups:   
        self.fields['km_stand'].widget.attrs['readonly'] = True

1👍

If you’re using Class Based Views (CBVs) then passing an extra argument in the form constructor (e.g. in get_forms_class) or in form_class will not work, as <form> object is not callable will be shown.

The solution for CBVs is to use get_form_kwargs to pass the user object to MyForm:

views.py:

form_class = MyForm

# Sending user object to the form, to verify which fields to display/remove (depending on group)
def get_form_kwargs(self):
    kwargs = super(MyView, self).get_form_kwargs()
    kwargs.update({'user': self.request.user})
    return kwargs

forms.py:

class MyForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')  # To get request.user. Do not use kwargs.pop('user', None) due to potential security hole

        super(MyForm, self).__init__(*args, **kwargs)

        # If the user does not belong to a certain group, remove the field
        if not self.user.groups.filter(name__iexact='mygroup').exists():
            del self.fields['confidential']

0👍

No I did not use class based Views:
I found the solution, also valid for function based views.
The user group could be retrieved in the view.py and assigned to the form:

gr = request.user.groups.values_list('name', flat=False)
...
form = gwagen1Form(gr, request.POST)

if form.is_valid():
    (do something)
else:
    form = gwagen1Form(gr)

In the form.py the init method will retrieve the user groups:

def __init__(self, *args, **kwargs):
    super(gwagen1Form, self).__init__(*args, **kwargs)
    self.fields["verk_num"].initial = benutzer.objects.get(flag_default=True)

    # Rolle einlesen
    gr = Group()
    if gr:
        self.fields['km_stand'].widget.attrs['readonly'] = True

Leave a comment