14

Hi Stackoverflow people,

In my clean function in forms.py, I would like to save automatically some information in a session variable. However, I do not seem to get access to the request variable.

All examples for handing over the request variable are based on function based views, but here I am using a class based view.

My forms.py:

from django import forms
from item.models import Item

class CreateItemForm(forms.ModelForm):
    class Meta:
        model = Item
        fields = ('name', 'description')

    def __init__(self, request, *args, **kwargs):
        self.request = request
        super(CreateItemForm, self).__init__(*args, **kwargs)

    def clean(self):
        cleaned_data = super(CreateItemForm, self).clean()
        if cleaned_data.get("address"):
            self.request.session['name'] = cleaned_data.get("name") 
        else:
            raise forms.ValidationError(_('Oops, can\'t find location.'))
        return self.cleaned_data

My views.py:

from django.views.generic.edit import FormView
from item.forms import CreateItemForm

class ItemCreate(FormView):
    form_class = CreateItemForm 
    template_name = 'item/item_create.html' 
    success_url = 'http://www.google.com'

What is the best way to hand over the request variable from the views.py to forms.py?

Thank you for your answer.

neurix
  • 4,126
  • 6
  • 46
  • 71
  • You can pass it to __init__, assign it there to self.request, and access it from clean. – Jure C. Aug 21 '12 at 22:34
  • I have tried to replace `form_class = CreateItemForm` with `form_class = CreateItemForm(request)`, but it caused more problems. Or do you mean a different solution? – neurix Aug 21 '12 at 22:35
  • I have explained a way more simpler solution in [this stackoverflow link.](https://stackoverflow.com/questions/43237742/django-pass-data-from-cbv-form-view-to-form-cbv/63314035#63314035) – Swarup Selvaraj Aug 18 '20 at 19:16
  • I have posted a more simpler solution [in this StackOverflow link.](https://stackoverflow.com/questions/43237742/django-pass-data-from-cbv-form-view-to-form-cbv/63314035#63314035) – Swarup Selvaraj Aug 18 '20 at 19:18

2 Answers2

18

You can overwrite the FormMixin's get_form_kwargs method to add the request for to the form's init parameters:

class ItemCreate(FormView):
     def get_form_kwargs(self):
         kwargs = super(ItemCreate, self).get_form_kwargs()
         kwargs.update({
             'request' : self.request
         })
         return kwargs
Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • 1
    I have added the method to the class based view, but then the `__init__() method` of the form is throwing the following error `__init__() got an unexpected keyword argument 'request'`. Do you know why? – neurix Aug 21 '12 at 22:45
  • 5
    `request` should be a keyword arg: `def __init__(self, request=None, *args, **kwargs):` – Timmy O'Mahony Aug 21 '12 at 22:47
  • Should it be the same to do this with an UpdateView? I tried adding your amended `get_form_kwargs` but I'm getting `name 'request' is not defined`. – KindOfGuy Sep 24 '13 at 22:17
0

Overriding the form.get_initial() works for me

class ItemCreate(FormView):
    def get_initial(self):
        init = super(ItemCreate, self).get_initial()
        init.update({'request':self.request})
        return init

And in the clean we can access it with form.initial dict

class sampleForm(forms.Form):
    ...
    ...
    def clean(self):
    user_request = self.initial['request']

By the way, we don't need to pop the extra args like suggested above.

bvemu
  • 1
  • 2