3

I'm using the FormWizard functionality in Django 1.4.3.

I have successfully created a 4-step form. In the first 3 steps of the form it correctly takes information from the user, validates it, etc. In Step #4, it right now just shows a "Confirm" button. Nothing else. When you hit "Confirm" on step #4, does something useful with it in the done() function. So far it all works fine.

However, I would like to make it so that in step 4 (The confirmation step), it shows the user the data they have entered in the previous steps for their review. I'm trying to figure out the most painless way to make this happen. So far I am creating an entry in the context called formList which contains a list of forms that have already been completed.

class my4StepWizard(SessionWizardView):

    def get_template_names(self):
        return [myWizardTemplates[self.steps.current]]

    def get_context_data(self, form, **kwargs):
        context = super(my4StepWizard, self).get_context_data(form=form, **kwargs)
        formList = [self.get_form_list()[i[0]] for i in myWizardForms[:self.steps.step0]]

        context.update(
            {
                'formList': formList,
            }
        )
        return context        


    def done(self, form_list, **kwargs):
        # Do something here.
        return HttpResponseRedirect('/doneWizard')

Form #1 has an input field called myField. So in my template for step #4, I would like to do {{ formList.1.clean_myField }}. However, when I do that, I get the following error:

Exception Value:
'my4StepWizard' object has no attribute 'cleaned_data'

It seems that the forms I am putting into formList are unbounded. So they don't contain the user's data. Is there a fix I can use to get the data itself? I would really like to use the context to pass the data as I'm doing above.

Saqib Ali
  • 11,931
  • 41
  • 133
  • 272

1 Answers1

2

Try this:

def get_context_data(self, form, **kwargs):
    previous_data = {}
    current_step = self.steps.current # 0 for first form, 1 for the second form..

    if current_step == '3': # assuming no step is skipped, this will be the last form
        for count in range(3):
            previous_data[unicode(count)] = self.get_cleaned_data_for_step(unicode(count))

    context = super(my4StepWizard, self).get_context_data(form=form, **kwargs)
    context.update({'previous_cleaned_data':previous_data})
    return context

previous_data is a dictionary and its keys are the steps for the wizard (0 indexed). The item for each key is the cleaned_data for the form in the step which is the same as the key.

Tundebabzy
  • 829
  • 2
  • 11
  • 24
  • 1
    There are three problems with this solution: Problem #11) range(4) should be range(3) Problem #2) self.steps.current is not an integer. It is the name of a form. Problem #3) Even when I fix for #1 and #2, previous_data looks like this: {0: None, 1: None, 2:None}. There is no Data there. – Saqib Ali Feb 14 '13 at 00:10
  • You are right about the issues. I posted the answer way beyond my bed time. I have edited the post to check for '3' not 3. I have something similar to this in production code and it works. if you are not supplying an int or a string that will not pass as a correct form step e.g '0', '1' not 'confirmation' or 'first_page', I don't see any reason why you should be getting None – Tundebabzy Feb 14 '13 at 09:53
  • Thanks for responding and making those fixes Tundebabzy. However, the underlying issue is that self.get_cleaned_data_for_step(unicode(count)) always returns None. – Saqib Ali Feb 14 '13 at 17:05
  • **scratching my head** but do post here when you get the issue fixed anyway. I'm eager to know how you fix this – Tundebabzy Feb 14 '13 at 18:07
  • Ok, If I ever find the answer, I will post it here. FYI "cleaned_data_for_step" should be "get_cleaned_data_for_step". – Saqib Ali Feb 14 '13 at 23:01