Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django form wizard - choices depending on first form step

I have created a 2 step form with the FormWizard as follows:

  • 1st step: asking user for location
  • 2nd step: show several search results depending on the user location, and display it as radioButtons

Now the second form depends on the input of the first form. Several blogs or stackoverflow posts cover similar topics, and I followed the instructions. However, the variable which is supposed to be saved during the process_step is not available for the next _init_.

How do I communicate the variable location from the process_step to _init_?

class reMapStart(forms.Form):
    location = forms.CharField()
    CHOICES = [(x, x) for x in ("cars", "bikes")]
    technology = forms.ChoiceField(choices=CHOICES)

class reMapLocationConfirmation(forms.Form):

   def __init__(self, user, *args, **kwargs):
       super(reMapLocationConfirmation, self).__init__(*args, **kwargs)
       self.fields['locations'] = forms.ChoiceField(widget=RadioSelect(), choices=[(x, x)  for x in location])

class reMapData(forms.Form):
   capacity = forms.IntegerField()

class reMapWizard(FormWizard):
   def process_step(self, request, form, step):
       if step == 1:
          self.extra_context['location'] = form.cleaned_data['location']

   def done(self, request, form_list):
       # Send an email or save to the database, or whatever you want with
       # form parameters in form_list
       return HttpResponseRedirect('/contact/thanks/')

Any help is absolutely appreciated.

Thanks, H

PS: posting was updated with newer code.

like image 551
Hannes Avatar asked Feb 19 '11 09:02

Hannes


1 Answers

I figured you could just access the POST dictionary directly in your __init__ method because it looks like the wizard passes POST into each form instance via get_form, but I don't see the data for some reason.

Instead of dwelling on that too long the alternative I've come up with is using the render_template hook.

class ContactWizard(FormWizard):
    def done(selef, request, form_list):
        return http.HttpResponse([form.cleaned_data for form in form_list])

    def render_template(self, request, form, previous_fields, step, context=None):
        """
        The class itself is using hidden fields to pass its state, so
        manually grab the location from the hidden fields (step-fieldname)
        """
        if step == 2: 
            locations = Location.objects.filter(location=request.POST.get('1-location'))
            form.fields['locations'].choices = [(x, x) for x in locations]
        return super(ContactWizard, self).render_template(request, form, previous_fields, step, context)
like image 100
Yuji 'Tomita' Tomita Avatar answered Sep 20 '22 06:09

Yuji 'Tomita' Tomita