2012-11-20 42 views
0

完整的問題陳述涉及多個步驟,然而,在它的心臟是這個簡單的場景:如何使用WizardView(Django 1.4)創建動態表單?

可以說我有兩種形式

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和填充choice_field當窗體2是被退回。它確實在呈現的表單中顯示了選項,但該表單在提交時未進行驗證。

我的直覺說,這應該是可能的,「如何」是什麼,我無法弄清楚。

回答

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

它將工作。但也許你選擇了錯誤的應用程序架構

+0

是的,我已經嘗試過了。選項以表格形式顯示,但驗證失敗,說明選定的值不是一個有效的選擇。 –

+0

哦。抱歉。我沒有測試過這個。我的錯。現在看起來就像工作例子。當字段填充數據時更改條件。 –

1

優於從不遲到......我最近碰到這種情況下我自己,不得不重寫表單(第二步)init方法,並從WizardView的形式傳遞一個最初的關鍵字。從那裏我可以有條件地設置表單域的選擇。

我自己implementation-

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」),並根據用戶輸入在第一步驟中,改變在第二步驟中的形式顯示在一個choicefield的選擇。