完整的问题陈述涉及多个步骤,但其核心是这个简单的场景:
假设我有两种形式
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()
现在使用django.contrib.formtools.wizard.views.WizardView
或其子类我想使用char_field1
- char_field3
中用户填充的选项填充choice_field。
我尝试覆盖get_form
并在返回Form2时填充choice_field。它确实显示了呈现的表单中的选项,但表单在提交时未验证。
我的直觉觉得它应该是可能的,'怎么样'是我无法弄清楚的。
答案 0 :(得分:1)
迟到总比没有...我最近自己遇到了这种情况,不得不重写表单(第二步)的init方法,并将一个初始关键字从WizardView传递给表单。从那里我可以有条件地设置表单字段的选择。
我自己的实施 -
views.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
forms.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'),并根据第一步中的用户输入,在第二步中更改选项字段中显示的选项。形式。
答案 1 :(得分:0)
你可以这样做:
views.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
urls.py:
from app.forms import Form1, Form2
from app.views import ChoiceWizardView
urlpatterns = patterns('',
(r'^my_wizard/$', ChoiceWizardView.as_view([Form1, Form2])),
)
它会起作用。但也许您选择了错误的应用程序架构?