Create Data Once in a FormWizard

Posted by in Software

At one of the sites I’m building I need to walk users through a registration process:

  1. Select a supported tool
  2. Generate an ID
  3. Create a configuration based on the previous two steps

To do this, I chose to use a FormWizard with three steps, one for each of the above. The problem then becomes to generate the ID once per wizard iteration.

Initial Approach(es)

Various online solutions (and even in the FormWizard documentation) suggest using get_form_kwargs() or get_form_initial() to build step-relevant data coupled with the get_cleaned_data_from_step().

The get_form_initial() method is designed to provide initial data for a particular form. It’s quite useful and a sample code can look like this:

A solution based on the get_form_kwargs() is similar, but the form needs to process the generated kwargs. Thus, we need to build code both in the wizard:

and in the form:

Both solutions can be used to provide initial data to a form. However, if you use get_form_initial() with get_cleaned_data_for_step(), you can end up with recursion issues as the latter will call the former with the given step parameter.

In my case, the STEP_UID step would generate a new UID which the wizard would use to build a configuration. Given the above approach, the code generating the UID would get called every time the validation for the ID form would be called. This would result in extra UIDs being created, although the FormWizard will persist your correct value.

My Solution

In order to avoid proliferation of IDs, I need a way to persist the information around. I’ve tried the context variable, but access to it is difficult from within e.g. the get_form_initial() method (read: I wasn’t able to find a way).

The next best thing is to do a session-based binding. The instance_dict object field is bound to the instance and I can use it to store my ID for future use. The new, adjusted function is:

This way, we generate the ID only if it’s not in the instance_dict.

Note: We need to clean up the dictionary at the end:

HTH,


A little experiment: If you find this post and ad below useful, please check the ad out :-)