0

The full problem statement involves multiple steps, however, at the heart of it is this simple scenario:

Lets say I have two forms

from django import forms

class Form1(forms.Form):
    char_field1=forms.CharField(label='field 1')
    char_field2=forms.CharField(label='field 2')
    char_field3=forms.CharField(label='field 3')

class Form2(forms.Form):
    choice_field = forms.ChoiceField()

Now using django.contrib.formtools.wizard.views.WizardView or its subclass I would like to populate the choice_field with the options filled by the user in char_field1 - char_field3.

I tried overriding the get_form and populating the choice_field when Form2 was to be returned. It did show the options in the form rendered, but the form didn't validate upon submission.

My gut feel says that it should be possible, the 'how' is what I am not able to figure out.

4

2 回答 2

1

迟到总比没有好...我自己最近遇到了这种情况,不得不重写表单的(第二步)init方法并将一个初始关键字从WizardView传递给表单。从那里我可以有条件地设置表单字段的选项。

我自己的实现-

视图.py

class QuoteWizard(SessionWizardView):
    form_list = [QQFormProductLine, QQProduct, QQProductFluidProperties]
    ...
    def get_form_initial(self, step):
        #pass variables to forms from here
        initial = self.initial_dict.get(step, {})
        if int(step) > 0:
            self.temperature_units, self.measurement_format = self.get_measurement_units()
            initial.update({'measurement_format': self.measurement_format})
        return initial

表格.py

class QQProduct(forms.ModelForm):
    ...
    def __init__(self, *args, **kwargs):
        super(QQProduct, self).__init__(*args, **kwargs)
        units = None 

        if 'initial'in kwargs:
            initial = kwargs.pop('initial')
            if 'measurement_format' in initial:
                units = initial.pop('measurement_format')

        flow_choices = []
        if units == 'imperial':
            flow_units = qq_models.FlowRateUnits()
            flow_units = flow_units.imperial()
        elif units == 'metric':
            flow_units = qq_models.FlowRateUnits()
            flow_units = flow_units.metric()

        for i in flow_units:
            flow_choices.append((i, qq_models.FlowRateUnits.get(i)))
        if len(flow_choices) > 0:
            self.fields['flow_rate_format'].widget.choices = flow_choices

总之,get_form_initial 是一个 WizardView 方法,它将初始关键字传递给表单以执行一个步骤。在我的 self.get_measurement_units() 方法中,我调用 self.get_cleaned_data_for_step('0') 并根据第一步中的用户输入,更改第二步表单中选择字段中显示的选项。

于 2014-09-28T18:21:11.333 回答
0

你可以这样做:

视图.py:

from django.contrib.formtools.wizard.views import CookieWizardView

class ChoiceWizardView(CookieWizardView):
    def done(self, form_list, **kwargs):
        pass

    def get_form(self, step=None, data=None, files=None):
        form = super(ChoiceWizardView, self).get_form(step, data, files)
        if 'choice_field' in form.fields:
            form1_cleaned_data = self.get_cleaned_data_for_step('0')
            if form1_cleaned_data:
                form.fields['choice_field'].choices = [item for item in form1_cleaned_data.items()]
        return form

网址.py:

from app.forms import Form1, Form2
from app.views import ChoiceWizardView

urlpatterns = patterns('',
    (r'^my_wizard/$', ChoiceWizardView.as_view([Form1, Form2])),
)

它会起作用的。但也许你选择了错误的应用架构?

于 2012-11-20T19:15:58.230 回答