12

我有一个 FormWizard,我需要将第一个表单中的数据传递给第二个表单的构造函数,以便构建动态表单。

我可以通过 FormWizard 的 process_step 获取第一个表单的数据。

我使用字段列表的数据库调用来创建第二种形式的字段。

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

我怎样才能通过DATA_FROM_1STFORM


我的结果代码:我放弃了表单的初始化,并将其切换到 CreateQuestions def。然后使用向导的 get_form 覆盖在创建后更改表单。

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
4

4 回答 4

8

我通过覆盖 WizardView 的 get_form_kwargs 解决了这个问题。它通常只返回一个 get_form 填充的空字典,因此通过覆盖它以返回一个包含您需要预填充的数据的字典,您可以将 kwargs 传递给您的表单 init。

def get_form_kwargs(self, step=None):
    kwargs = {}
    if step == '1':
        your_data = self.get_cleaned_data_for_step('0')['your_data']
        kwargs.update({'your_data': your_data,})
    return kwargs

然后,在您的表单init方法中,您可以在调用 super 之前弹出 kwarg:

self.your_data = kwargs.pop('client', None)
于 2012-10-22T15:04:27.077 回答
5

FormWizard 已经将数据从每个前一个表单传递到下一个表单。如果您想获取该数据以实例化一个类(例如,如果一个表单具有它需要的特殊关键字参数),一种方法是通过get_form在您的表单向导类中覆盖来获取 querydict。例如:

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))

请注意,您还可以parse_params(self, request, *args, **kwargs)在 FormWizard 中覆盖以访问 url/请求数据,就像您在视图中一样,因此如果您有request.user所有表单都需要的请求数据(例如),它可能是最好从那里获取数据。

希望这可以帮助。

于 2010-11-11T17:29:15.827 回答
3

在视图中覆盖表单向导的 get_form_kwargs 方法

视图.py

class FormWizard(SessionWizardView):
    def get_form_kwargs(self, step=None):
        kwargs = {}
        if step == '1':
            step0_form_field = self.get_cleaned_data_for_step('0')['previous_form_field_data']
            kwargs.update({'step0_form_field': step0_form_field})
        return kwargs 

通过弹出从上一个字段中获得的数据来覆盖表单的初始化,以创建一个动态字段。

表格.py

class MyForm(forms.Form):
    #some fields

class MyForm1(forms.Form):
    def __init__(self, *args, **kwargs):
        extra = kwargs.pop('step0_form_field')
        super(MyForm1, self).__init__(*args, **kwargs)

        for i in range(extra):
            self.fields['name_%s' % i] = forms.CharField()
于 2013-08-28T08:29:49.653 回答
0

我最近正在使用 django 表单向导,我正在解决类似的问题。我认为您不能将数据传递给init,但是,您可以做的是覆盖init构造函数:

next_form = self.form_list[1]

# let's change the __init__
# function which will set the choices :P
def __init__(self, *args, **kw):
    super(next_form, self).__init__(*args, **kw)
    self.fields['availability'].choices = ...
next_form.__init__ = __init__

很烦人的是,在 python 中你不能一次性声明和分配一个函数,而必须把它放在命名空间中(除非你使用 lambdas),但是很好。

于 2010-10-16T23:52:38.543 回答