SessionWizardView state is saved only in final form, completed () not executed

I have several forms that I added to the wizard, but the state of the form is only supported for the last step, and done () is not executed.

I created the following, heavily based on django documentation examples, to try and figure this out. The last step seems to be the only one that keeps state when moving between steps.

class OneForm( Form ): field_one = forms.CharField(label='1', max_length=100) field_two = forms.CharField(label='2', max_length=100) field_three = forms.CharField(label='3', max_length=100) class TwoForm( Form ): field_one = forms.CharField(label='4', max_length=100) field_two = forms.CharField(label='5', max_length=100) field_three = forms.CharField(label='6', max_length=100) TEST_WIZARD_FORMS = [ ("one", OneForm), ("two", TwoForm), ] TEST_TEMPLATES = { 'one': 'tour/one.html', 'two': 'tour/two.html', } class TestWizardView( SessionWizardView ): form_list = TEST_WIZARD_FORMS def done(self, form_list, **kwargs): print('done executed') return reverse('home') def get_template_names(self): return [TEST_TEMPLATES[self.steps.current]] 

and this is for templates (both one.html and two.html are identical)

 <html> <body> <p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p> <form action="" method="post">{% csrf_token %} <table> {{ wizard.management_form }} {% if wizard.form.forms %} {{ wizard.form.management_form }} {{ wizard.form.non_field_errors }} {{ wizard.form.errors }} {% for form in wizard.form.forms %} {{ form }} {% endfor %} {% else %} {{ wizard.form }} {% endif %} </table> {% if wizard.steps.prev %} <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">"first step"</button> <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">"prev step"</button> {% endif %} <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.next }}">"next step"</button> <input type="submit" value="submit"/> </form> </body> </html> 

If I enter the data in step 1, go to step 2 and enter the data, and then go back to step 1, the first step will not save the data and will not display form errors. When I click next to returning to step 2, the data of the second step is still present. The deliberate placement of invalid data in step 1 showed me that it also does not confirm the form, as the wizard proceeds to step 2 without displaying errors.

When I submit the form, done () is not executed. It makes sense if only the last step was really successful, but the lack of errors in step 1 puzzled me.

Why are these forms not supported, except in the final form? Why is the last step the only one that actually validates the form data? Why is this not done?

Update:. It seems that form validation happens after everything, and I see that it succeeds by printing the relevant information in the post function, but done () still fails.

Thanks.

+6
source share
2 answers

Step 1 in the documentation found here is the answer. It indicates the following.

The user visits the first page of the wizard, fills out the form and submits it.

The key here is send. Validation of the form or state is not saved if the form is not submitted. Using wizard_goto_step for the next / previous / jump does not submit the form, does not validate the form and does not save the form in the session / cookie (depending on what you choose).

Now this is obvious, but I still think it is misleading to the potential end users of the form wizard. It’s enough for me to simply replace wizard_goto_step with the actual view when proceeding to the next step, but when users enter some data in the form and subsequently choose to review another step, all their data is lost at this stage.

It seems that the form data should be saved, even if they are incomplete. My intention is to save this data manually using the storage.set_step_data () function, since all steps of the form are re-checked for final processing in any case. Even if the user fills in the incorrect data in the step, they will still be redirected to the step with the missing data at the end. This seems like a better behavior than blindly wiping user data in a step when they visit the previous step.

+1
source

This is definitely a mistake. You must remove the following lines of code from

\ formtools \ Wizard \ views.py

  # walk through the form list and try to validate the data again. # for form_key in self.get_form_list(): # form_obj = self.get_form(step=form_key, # data=self.storage.get_step_data(form_key), # files=self.storage.get_step_files(form_key)) # if not form_obj.is_valid(): # return self.render_revalidation_failure(form_key, # form_obj, # **kwargs) # final_forms[form_key] = form_obj 

Actually, I don’t understand the reason for this code. Each form has been validated after submission. I see no reason to check them again?

This check is not performed for some unknown reason, and therefore the procedure performed is never called later.

0
source

All Articles