I have a FormWizard where I need data from the first form to pass to the constructor of the second form so I can build a dynamic form.
I can get the first form's data via the process_step of the FormWizard.
I create the fields of the second form with a database call of the list of fields.
class ConditionWizardDynamicQuestions(forms.Form):
def __init__(self, DynamicQuestions=None, *args, **kwargs):
super(ConditionWizardDynamicQuestions, self).__init__(*args, **kwargs)
questions = Question.objects.filter(MYDATA = DATA_FROM_1STFORM)
for q in questions:
dynField = FieldFactory(q)
self.fields[q.label] = dynField
How can I pass over the DATA_FROM_1STFORM ?
my resultant code: I abandoned the init of the form, and switched it to the CreateQuestions def. Then used the wizard's get_form override to alter the form after creation.
class ConditionWizard(SessionFormWizard):
def get_form(self, request, storage, step=None, data=None, files=None):
form = super(ConditionWizard, self).get_form(request, storage, step, data, files)
stepIndex = self.get_step_index(request, storage, step)
if stepIndex == 1:
form.CreateQuestions(request.session["WizardConditionId"])
if stepIndex == 3:
form.fields['hiddenConditionId'].initial = request.session["WizardConditionId"]
form.fields['medicationName'].queryset = Medication.objects.filter(condition = request.session["WizardConditionId"])
return form
FormWizard already passes the data from each previous form to the next form. If you want to get that data in order to instantiate a class (for example, if a form has special keyword arguments that it requires), one way of doing it is to grab the querydict by overriding get_form
in your form wizard class. For example:
class SomeFormWizard(FormWizard):
def get_form(self, step, data=None):
if step == 1 and data: # change this to whatever step requires
# the extra data
extra_data = data.get('key_from_querydict')
if extra_data:
return self.form_list[step](data,
keyword_argument=extra_data,
prefix=self.prefix_for_step(step),
initial=self.initial.get(step, None))
# Fallback for the other forms.
return self.form_list[step](data,
prefix=self.prefix_for_step(step),
initial=self.initial.get(step, None))
Note that you can also override parse_params(self, request, *args, **kwargs)
in FormWizard to access the url/request data, just like you would in a view, so if you have request data (request.user
, for instance) that is going to be needed for all of the forms, it might be better to get the data from there.
Hope this helps.