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


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?

5/12/2012 1:12:03 AM

Accepted Answer

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)
6/29/2009 10:36:55 AM

UPDATED 10/25/2011: I'm now using this with a metaclass instead of method, as Django 1.3 displays some weirdness otherwise.

class MyModelAdmin(admin.ModelAdmin):
    form = MyCustomForm
    def get_form(self, request, obj=None, **kwargs):
        ModelForm = super(MyModelAdmin, self).get_form(request, obj, **kwargs)
        class ModelFormMetaClass(ModelForm):
            def __new__(cls, *args, **kwargs):
                kwargs['request'] = request
                return ModelForm(*args, **kwargs)
        return ModelFormMetaClass

Then override MyCustomForm.__init__ as follows:

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

You can then access the request object from any method of ModelForm with self.request.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow