Django formwizard - cannot get data from step 1 to step 2

959 views Asked by At

I am using a Django form wizard to enter data into a form page, and then display it in a confirmation page. However, when I try to call self.get_cleaned_data_for_step(step_name), I get a "'MyForm' object has no attribute 'cleaned_data'." I know this can happen if the form fails to validate, so I overrode the is_valid method in my form class to always return True, just as a test, but I still get this error. My relevant code is below:

forms.py

...
class MealForm(forms.Form):

    modifications = forms.CharField()

    def __init__(self, *args, **kwargs):
        menu_items = kwargs.pop('menu_items')
        super(MealForm, self).__init__(*args, **kwargs)

        for item in menu_items:
            self.fields[str(item.name)] = forms.IntegerField(widget=forms.NumberInput(attrs={'value': 0}))

    def is_valid(self):
        return True

urls.py

...
url(r'^(?P<url>[-\w]+)/meal/$',
    login_required(views.MealFormWizard.as_view(views.MealFormWizard.FORMS)), name="meal"),

views.py

...
class MealFormWizard(SessionWizardView):

    FORMS = [('meal_form', MealForm),
             ('meal_form_confirmation', MealFormConfirmation)]

    TEMPLATES = {'meal_form': 'restaurant/createMeal.html',
                 'meal_form_confirmation':     'restaurant/confirmation.html'}

    def get_form_kwargs(self, step=None):
        kwargs = {}

        url = self.kwargs['url']
        restaurant = Restaurant.objects.get(url=url)
        menu_items = MenuItem.objects.filter(restaurant=restaurant)

        if step == 'meal_form':
            kwargs['menu_items'] = menu_items

        return kwargs

    def get_context_data(self, form, **kwargs):

        context = super(MealFormWizard, self).get_context_data(form=form, **kwargs)

        if self.steps.current == 'meal_form':
            context.update({...objects/vars...})

        if self.steps.current == 'meal_form_confirmation':
            cd = self.get_cleaned_data_for_step('meal_form') **This is where my error occurs**

createMeal.html

...
<form action="" method="post">
{% csrf_token %}
{{ wizard.management_form }}

{{ wizard.form }}

<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.next }}">Submit Meal</button>
</form>

Upon submitting the form in createMeal.html I should be able to access the cleaned data for the previous step in the get_context_data method of my MealFormWizard class in views.py via a call to self.get_cleaned_data_for_step('meal_form'). However, this is not the case, but I am not sure where I went wrong.

2

There are 2 answers

2
Alasdair On

Overriding is_valid like that won't work - if you follow the code you will see that the form's cleaned_data attribute is set by the normal is_valid method.

The docs say that if the form is invalid, then get_cleaned_data_for_step will return None, you need to write your code so it can handle this.

0
Adrian M On

In case this is helpful to anyone. My problem was that in my createMeal.html, my button was simply taking the wizard to the next step, bypassing any validation. The proper solution is to make a simple submit button to submit the form, at which point the wizard will then validate the form, and if it is valid, it will move on to the next step.