2010-11-27 56 views
7

我在模板中放置了一些客戶端Javascript,允許用戶動態添加字段到表單。我的問題是這些字段已在form.cleaned_data中清除,所以我無法以這種方式訪問​​它們。動態添加的表單域在form.cleaned_data中被刪除

所有的字段都可以在request.POST訪問,所以我可以用這個來解決這個問題,但我想這樣做是「正確的方式」,我認爲解決方案在於使用django表單而不是讀取請求直。

我試着覆蓋form.clean(),但是好像數據在它到達那裏時已經消失了。

其他詳情:我命名這些字段fieldname_x,其中x是一個數字。在request.POST中,request.POST['fieldname']是所有值的列表,但form.cleaned_data僅包含每個列表的最後一個值。

回答

2

你知道這些字段事先將會是什麼類型嗎?他們只是簡單的文本字段?我做了類似的事情,創建了動態表單。

# make sure these exist by examining request.POST 
custom_fields = ['fieldname_1', 'fieldname_2'] 

attrs = dict((field, forms.CharField(max_length=100, required=False)) 
      for field in custom_fields) 
DynamicForm = type("DynamicForm", (YourBaseForm,), attrs) 
submitted_form = DynamicForm(request.POST) 

您提交的表單現在應該包含您需要的所有字段及其值。你可能想刪除required = False,但這取決於你。

這是做什麼的,是執行你的基本形式的動態子類,將作爲attrs傳入的屬性添加到類定義中。因此,當您使用發佈數據創建實例時,應該正確映射它們。

編輯:

我仔細地讀了一下這個問題。你需要做的是確保你的動態輸入元素被正確命名,並且值到達django後映射到這些字段名。否則,request.POST將不會正確填寫表單。

<input type='text' name='fieldname_1' value='value_for_field_1' /> 

0

我在我目前工作的項目這樣做。你會想看看formsets。但要警告,這不是很漂亮。你必須修改這個存儲到表單計數的隱藏字段,並且你必須正確地重命名輸入。這涉及到很多無意義的字符串解析。如果他們使用的陣列,如PHP,就不會有問題,但他們一意孤行在使我的生活苦不堪言...... 漫步關

編輯: http://docs.djangoproject.com/en/dev/topics/forms/formsets/#empty-form他們提供這使得你的生活5%少痛苦...你可以做一個發現和前綴用適當的號碼替換..但我認爲我有一個問題,空表單不包含正確的默認值,如果你初始化形式與發佈數據,所以我不得不創建一個沒有發佈數據的第二個實例到一個實際爲空的empty_form,這只是遲緩。

+0

拉爾夫,我建議你已經走了關於它的很長的路要走。利用python和Django系統做事。在需要時動態創建模型和表單。看到我的答案。 – 2010-11-28 01:01:36

2

也可以在你的表單文件中完成這項工作,這裏是Jacob Kaplan-Mosse爲動態表單提供的一個很好的演示:http://jacobian.org/writing/dynamic-form-generation/適用於這個問題。

做什麼是添加一個方法給你表單類添加額外的動態字段,然後從乾淨的信息產生,以便您可以在您的視圖中獲得它。

class MyForm(forms.Form): 
    text = forms.CharField(max_length=30) 

    def __init__(self, *args, **kwargs): 
     extra = kwargs.pop('extra') 
     super(MyForm, self).__init__(*args, **kwargs) 

     for i, question in enumerate(extra): 
      self.fields['fieldname_%s' % i] = forms.CharField(label=question) 

    def extra_fields(self): 
     for name, value in self.cleaned_data.items(): 
      if name.startswith('fieldname_'): 
       yield (self.fields[name].label, value) 

,並從該視圖調用它:

def doSomething(request, extra_fields): 
    form = MyForm(request.POST or None, extra=extra_fields) 
    if form.is_valid(): 
     for (question, answer) in form.extra_answers(): 
      save_answer(request, question, answer) 
     return redirect("create_user_success") 

return render_to_response("template/form.html", {'form': form}) 

非常整潔,恭喜雅各卡普蘭,莫斯