Django:动态设置Formset for Form Wizard中的步骤

mzu*_*mzu 6 django django-forms django-formwizard

作为我的Django视图中的表单向导的一部分,我使用的是Formset.每个步骤的向导表单都声明如下:

UserFormSet = modelformset_factory(account_models.MyUser,
                                   form=account_forms.MyUserForm, 
                                   extra=5, 
                                   max_num=10, 
                                   can_delete=True)

FORMS = [('userchoice', UserChoiceForm),
         ('user', UserFormSet),]
TEMPLATES = {'userchoice': "account/userchoice.html",
             'user': "account/user.html",}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是:在UserChoiceForm(第一步)中,可以设置所需用户的数量.我想使用此值动态设置UserFormSet上的额外属性,以便在第二步中只显示所需数量的表单.

我试图通过覆盖向导的get_form()方法来做到这一点:

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

     # Determine the step if not given
     if step is None:
         step = self.steps.current

     if step == 'user':
         # Return number of forms for formset requested 
         # in previous step.
         userchoice = self.get_cleaned_data_for_step('userchoice')
         num_users = userchoice['num_users']
         CoFunderFormSet.extra = num_users
         return CoFunderFormSet
     return form
Run Code Online (Sandbox Code Playgroud)

使用这种方法,我能够为第二步显示正确数量的表单,但是当尝试发布Formset时,我最终会遇到此错误:

[u'ManagementForm data is missing or has been tampered with']
Run Code Online (Sandbox Code Playgroud)

POST数据具有预期的管理表单字段集,例如

form-TOTAL_FORMS    u'1'
Run Code Online (Sandbox Code Playgroud)

但我假设FormWizard使用的是初始FORMS列表中设置的Formset,因此管理表单不匹配.

我想知道是否有一个解决方案,如果有一种方法告诉FormWizard在POST上使用动态生成的Formset.

小智 6

您可以覆盖get_form_initial,假设您已经设置了form_list这样的:

form_list = [
        (FIRST_STEP, forms.FirstForm),
        (SECOND_STEP, modelformset_factory(Second_model, form=forms.SecondForm)),
    ]

def get_form_initial(self, step):
        """
        Set extra parameter for step2, which is from clean data of step1.
        """
        if step == self.SECOND_STEP:
            form_class = self.form_list[step]
            data = self.get_cleaned_data_for_step(self.FIRST_STEP)
            if data is not None:
                extra = get_extra_count(data) # use cleaned data calculate extra
                form_class.extra = extra
        return super(PackageWizard, self).get_form_initial(step)
Run Code Online (Sandbox Code Playgroud)


Nir*_*ran 0

如果您收到此错误消息,

[u'管理表单数据丢失或已被篡改']

在您的模板中,请确保您已给出{{ wizard.form.management_form }}.