2013-05-08 54 views
0

我想編寫一個視圖,該表單顯示多個表單,每個表單對應於由對象查詢返回的每個模型實例。這樣用戶可以一次填寫多個表單,然後所有對象的數據都會保存在POST上。下面是我有:Django多表單提交:覆蓋所有表單對象的一種表單

查看:

def formView(request, attr): 
    object_list = MyModel.objects.filter(attribute1=attr) 
    if request.method == 'POST': 
      form_list = [MyModelForm(request.POST, instance=x) for x in object_list] 
      if all(form.is_valid for form in form_list): 
       for form in form_list: 
        form.save() 
       return HttpResponseRedirect('/thanks/') 
    else: 
      form_list = [MyModelForm(instance=x) for x in object_list] 
    return render(request, 'formView.html', {'form_list':form_list}) 

HTML:

<table> 
     <thead> 
      <tr> 
       <th>Field1</th> 
       <th>Field2</th> 
       <th>Field3</th> 
      </tr> 
     </thead> 
     <tbody> 
      {% for form in form_list %} 
      <tr> 
       <form method="post">{% csrf_token %} 
       {% for field in form %} 
       <td>{{ field }}</td> 
       {% endfor %} 
       <td><input type="submit" value="Submit" /></td> 
       </form> 
      </tr> 
      {% endfor %} 
     </tbody> 
    </table> 

糾正我,如果我錯了,但這裏是我覺得目前我的代碼是這樣做的:當用戶填寫然後點擊頁面上的表格,然後點擊Submit按鈕中的一個,對應於該Submit按鈕的表單將僅將其數據發送到我的視圖,然後繼續將該數據保存到form_list中的所有表單中,從而編寫相同的數據至 我的數據庫中的所有對應的對象(這顯然不是我想要的)。

我想要的是類似於整個頁面的單個Submit按鈕,以便頁面中每個表單的數據都以其關聯的形式發回並保存到數據庫中相應的對應對象。這可能嗎?

+0

瀏覽器將只發送表格提交按鈕與相關的,它不會提交別人。這只是W3C瀏覽器的行爲。因此,每個'

'都有自己的方法(GET/POST)和動作URI。你想要的是使用FormSet,現在已經回答了;請注意,它使用單個表單元素進行呈現。 – gertvdijk 2013-05-08 08:25:32

回答

3

您是否嘗試過與模型關聯的FormSet?您可以定義查詢來選擇要編輯的對象,並且Django會處理(幾乎)所有內容。 https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#changing-the-queryset

如果你想追求你的方法(每頁一個以上的表格,或每頁面多個表單集)使用prefix屬性: https://docs.djangoproject.com/en/dev/ref/forms/api/#subclassing-forms ,並且只使用一個<form>標籤與單個Submit按鈕。

的例子: http://docs.djangoproject.com/en/dev/topics/forms/formsets/#using-more-than-one-formset-in-a-view

+0

我嘗試了FormSet方法,因爲我喜歡使用Django的所有「包含電池」部分,但後來意識到它不會工作,因爲我需要排除其中一個表單域,但仍顯示其值,而且我可以' t在'{form for form in form%}'循環中執行該操作。然而,'prefix'方式工作的很好,+1表示我只需要一個''標籤和一個'Submit'按鈕。 – GChorn 2013-05-08 08:46:47

+0

我最近纔開始使用表單,所以我不確定當你說你不能排除一個表單域時,我明白你的意思。你是否嘗試使用這裏解釋的第三種方法? https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-the-formset-in-the-template 問題是什麼? – 2013-05-08 08:58:14

+0

排除表單字段不是問題,當我使用'{form for formset%}'循環表單時,問題出現在我的模板中。如果在定義我的formset時排除字段,它將不會出現在我的模板中該循環內部的任何形式中。但我仍想顯示排除字段的數據,並且我無法訪問我的formset中的數據。因此,使用'prefix'方法,而不是將簡單的'form_list'從我的代碼示例發送到我的模板,而是創建'value,form'元組列表,然後我可以同時在模板中循環。 – GChorn 2013-05-08 09:33:06

1

嘗試在形式使用prefix,使得每個形式單獨識別。 x.id對於前綴會更好。

喜歡的東西:

def formView(request, attr): 
    object_list = MyModel.objects.filter(attribute1=attr) 
    if request.method == 'POST': 
      form_list = [MyModelForm(request.POST, instance=x, prefix=str(x.id)) for x in object_list] 
      if all(form.is_valid for form in form_list): 
       for form in form_list: 
        form.save() 
       return HttpResponseRedirect('/thanks/') 
    else: 
      form_list = [MyModelForm(instance=x, prefix=str(x.id)) for x in object_list] 
    return render(request, 'formView.html', {'form_list':form_list}) 
+0

感謝您的迴應!這似乎是實現我所需要的最快捷的方式,因爲它只需對代碼進行最小限度的更改。但是,現在當用戶單擊其中一個表單上的「提交」時,其餘表單將變爲空白,並觸發這些表單的所有「field.errors」。爲什麼會發生? – GChorn 2013-05-08 08:35:34

+0

@GChorn,檢查你在'request.POST'中獲取所有表單的數據。 – Rohan 2013-05-08 08:38:13

+0

我通過閱讀其他答案意識到了這個問題 - 使用這種方法,我只需要使用一個''標籤,只有一個'Submit'按鈕,然後只需遍歷該''''元素內的'form_list'。 – GChorn 2013-05-08 08:43:31