Edit: After some re-writes of this post it is finally setup in a manor that is clean and failsafe.

After researching and setting up two FormWizards in Django I concluded some things that might be useful to others. Hence this post.

Having userdata available throughout the wizard

I’ve seen some solutions on the net for this but when you handle data from several models over different steps the best way to handle this is using Django’s session framework. In parse_params() in the beginning and end we repectively get/set data and store our data.

def parse_params(self, request, *args, **kwargs):
    current_step = self.determine_step(request, *args, **kwargs)
    form = self.get_form(current_step, request.POST)

    # Pickup the dict from the users session or create a new one
    wizdata = request.session.get('wizdata') or {}

    # Your code goes here. E.g. set a value in the dict
    wizdata['some_key'] = 'Some value'

    # Store the possibly changed dict back in the users session.
    request.session['wizdata'] = wizdata

So whatever you do with the user data, it’s safe, and we can access it in any step throughout the wizardry.

def render_template(self, request, form, previous_fields, step, context=None):
    wizdata = request.session.get('wizdata')

    # Your other code goes here. E.g. a conditional on previously set data.
    if wizdata.get('some_key'):
        # Do something with your data
        wizdata['some_key'] = 'Some other value'

    # And again, simply store the dict in the users session.
    request.session['wizdata'] = wizdata

You can imagine that in the parse_params() and the render_template() method you respectively have the ‘if current_step == ‘ or ‘if step == ‘ statements along the way. All having the wizdata dict available.

This also works in the done() method. Simply get the dict one last time from the user session.

def done(self, request, form_list):
    wizdata = request.session.get('wizdata')

    # Other code here

    # Cleanup
    del request.session['wizdata']

Then, for tidyness, at the end of done() we remove the dict from the user session.

Gotchas

There can be stale data, in the form of our stored dicts, left behind when wizard sessions are not finished by the user. This also is true for the sessions itself. As stated in the The Django docs about sessions you should clean up the sessions from time to time.

Anybody that has improvements, questions or compliments please drop me a line 🙂

GrtzG