Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access the request object or any other variable in a form's clean() method?

Tags:

python

django

I am trying to request.user for a form's clean method, but how can I access the request object? Can I modify the clean method to allow variables input?

like image 266
nubela Avatar asked Jun 29 '09 08:06

nubela


2 Answers

The answer by Ber - storing it in threadlocals - is a very bad idea. There's absolutely no reason to do it this way.

A much better way is to override the form's __init__ method to take an extra keyword argument, request. This stores the request in the form, where it's required, and from where you can access it in your clean method.

class MyForm(forms.Form):      def __init__(self, *args, **kwargs):         self.request = kwargs.pop('request', None)         super(MyForm, self).__init__(*args, **kwargs)       def clean(self):         ... access the request object via self.request ... 

and in your view:

myform = MyForm(request.POST, request=request) 
like image 80
Daniel Roseman Avatar answered Oct 05 '22 04:10

Daniel Roseman


For what it's worth, if you're using Class Based Views, instead of function based views, override get_form_kwargs in your editing view. Example code for a custom CreateView:

from braces.views import LoginRequiredMixin  class MyModelCreateView(LoginRequiredMixin, CreateView):     template_name = 'example/create.html'     model = MyModel     form_class = MyModelForm     success_message = "%(my_object)s added to your site."      def get_form_kwargs(self):         kw = super(MyModelCreateView, self).get_form_kwargs()         kw['request'] = self.request # the trick!         return kw      def form_valid(self):         # do something 

The above view code will make request available as one of the keyword arguments to the form's __init__ constructor function. Therefore in your ModelForm do:

class MyModelForm(forms.ModelForm):     class Meta:         model = MyModel      def __init__(self, *args, **kwargs):         # important to "pop" added kwarg before call to parent's constructor         self.request = kwargs.pop('request')         super(MyModelForm, self).__init__(*args, **kwargs) 
like image 20
Joseph Victor Zammit Avatar answered Oct 05 '22 05:10

Joseph Victor Zammit