Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django: how to access current request user in ModelForm?

In my implementation of ModelForm, I would like to perform different types of validation checks based on whether current user is superuser. How can I access the current request user?

like image 234
zer0stimulus Avatar asked Sep 04 '11 14:09

zer0stimulus


2 Answers

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(), e.g.:

views.py:

class MyUpdateView(UpdateView):      model = MyModel     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(MyUpdateView, 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'] 
like image 82
SaeX Avatar answered Sep 25 '22 13:09

SaeX


you can pass the user object as an extra argument in the form constructor.

e.g.

f = MyForm(user=request.user) 

and the constructor will look like:

class MyForm(forms.ModelForm):     def __init__(self, *args, **kwargs):          self.user = kwargs.pop('user',None)          super(MyForm, self).__init__(*args, **kwargs) 

and then use user in the clean_XX forms as you wish

like image 33
alampada Avatar answered Sep 21 '22 13:09

alampada