How to pass user object to Django form

Nov. 27, 2020, 2:39 a.m.

Sometimes we want to use the user object in Django forms , the user object may be used in validation or even in querying the database. In this tutorial we are going to see how we can achieve that .

In your views.py file you need to pass the request as a keyword argument to our form , assume our form is called PostForm.

form = PostForm( ... ,  request =  request  )

And then in your forms.py file you will modify it like this



class PostForm(ModelForm):
     class Meta:
         model = Post

         fields = ['title', 'content']

     def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request") # store value of request 
        print(self.request.user) 
        super().__init__(*args, **kwargs)




     def clean(self):
        print(self.request.user) # request now available here also
        pass


What we did here is we passed the request to the constructor and store it as an instance variable so it can also be accessed by the clean method below it.

Once you have the request object, you can now get the user object from it .

The reason why we used kwargs.pop("request") is because the Form's default __init__ method does not expect a user argument , so kwargs.pop("request") is the best in this case since we get the value of request and at the same time it is removed from the the arguments passed to the __init__ method of our superclass.

If you try using kwargs.get("request") instead of kwargs.pop("request") you will get this error

TypeError: __init__ got an unexpected keyword argument 'request'

And this is because .get() method in python is used to get the the value of the item but it does not remove it from the dictionary the way .pop( ) method does.

if this is confusing you can checkout this tutorial I created What is super() in python so as to understand the meaning of super in python.

Now if you are using class based views (In Django we have function based and class based views, it is important to know the difference ) you would do it like this in your views.py file .


class PostCreateView(LoginRequiredMixin, CreateView):

    ... 

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update({'request': self.request})
        return kwargs

the forms.py file will remain the same .

Resources

Keep Learning