Django wizard forms and dynamic formset creation

546 Views Asked by At

Usually, in a wizard, we declare forms or formsets in static way, for example with something like:

form_class=formset_factory(MyForm, min_num=1, extra=5)  # let's say this is step '4'

But now, what if I need data from step 3, to know how to define the min_num or extra value for the formset of step 4?

I was thinking of doing such thing in the get_form() method:

def get_form(self, step=None, data=None, files=None):
    form = super().get_form(step, data, files)

    # ....

    elif step == '4':
        step3_data = self.storage.get_step_data('3')

        # ... here I would parse step 3 data, to be able to define:
        computed_step_4_min_num = 5
        computed_step_4_extra = 10

        # And here I would need to call formset_factory(min_num=computed_step_4_min_num,
                                                        extra=computed_step_4_extra),
        # but how? This is obviously not the right place for this call.

While it's easy to edit form fields attributes in the get_form() method, I did not find a way to define the right number of forms of a formset, in a dynamic way.

I read documentation but I could have missed it. Thanks for your help.

1

There are 1 best solutions below

0
ruddra On

By reading the documentation and checking the source code, I think this is the optimal solution to use:

def get_form(self, step=None, data=None, files=None):
    if step == '4':
        step3_data = self.storage.get_step_data('3')
        # do calculations
        computed_step_4_min_num = 5
        computed_step_4_extra = 10
        form = formset_factory(MyForm, min_num=computed_step_4_min_num, extra=computed_step_4_extra)
        self.form_list[step] = form
    return super().get_form(step, data, files)

I am overriding the self.form_list to add the formset factory. But you should add a formset in the view when initiating the Wizard instance:

>> formset = formset_factory(MyForm, min_num=1, extra=1)
>> MyWizardForm.as_view([Form1, Form2, Form3, formset], initial_dict=initial)