2011-05-25 37 views
1

我有一個ForeignKey和在線表單集相關的兩種型號:get_or_create兩個相關的模型表單集

class Balanta(models.Model): 
    data = models.DateField() 

    class Meta: 
     ordering=['data'] 
     verbose_name_plural="Balante" 

    def __unicode__(self): 
     return unicode(self.data) 

class Conturi(models.Model): 
    cont=models.PositiveIntegerField() 
    cont_debit=models.DecimalField(default=0, max_digits=30, decimal_places=2) 
    cont_credit=models.DecimalField(default=0, max_digits=30, decimal_places=2) 
    balanta = models.ForeignKey(Balanta) 

    class Meta: 
     #oredering=['cont'] 
     verbose_name_plural="Conturi" 

    def __unicode__(self): 
     return unicode(self.cont) 

我有一個基於這兩個模型表單集。我提交表格後,如果「表格的巴蘭塔部分」存在,表格不應該做任何不適當的事情,它應該保存在數據庫中(我設法做到這一點)。

現在我想要在「表單的Conturi部分」上執行的操作是查看cont是否在數據庫上,表單應該使用輸入框中的值更新它,如果它不在db中,表單應該創建它以及相應的cont_debit或cont_credit。當前狀態給了我:在**之後的get_or_create()參數必須是映射,而不是列表。

我認爲是更大的然後MT簡單/新手方式來解決問題。

這裏是視圖:

* 最後更新 *

from django.http import HttpResponseRedirect 
from django.shortcuts import get_object_or_404, render_to_response 
from django.template import RequestContext 
from sitfin.models import Balanta, Conturi 
from sitfin.forms import BalantaForm , ConturiForm 
from django.forms.models import inlineformset_factory 

def balanta_introducere(request): 
    balanta=Balanta() 
    ConturiInlineFormSet=inlineformset_factory(Balanta, Conturi, extra=3) 
    if request.method=='POST': 
     balanta_form=BalantaForm(request.POST, instance=balanta) 
     if balanta_form.is_valid(): 
      balanta, created=Balanta.objects.get_or_create(**balanta_form.cleaned_data) 
      #return HttpResponseRedirect('/sitfin/balantaok') 
     formset=ConturiInlineFormSet(request.POST, request.FILES, instance=balanta) 
     if formset.is_valid(): 
      #formset.save() 
      for form in formset: 
       data={ 
         'cont':form.cleaned_data.get('cont'), 
         'cont_debit':form.cleaned_data.get('cont_debit'), 
         'cont_credit':form.cleaned_data.get('cont_credit'), 
         'balanta':form.cleaned_data.get('balanta'), 
       } 
       try: 
        c=Conturi()#.objects.get(cont=data['cont']) 
       except Conturi.DoesNotExist: 
        cont_complete,created=Conturi.objects.get_or_create(**data) 
       else: 
        for form in formset: 
         new_data={ 
           'cont':form.cleaned_data.get('cont'), 
           'cont_debit':form.cleaned_data.get('cont_debit'), 
           'cont_credit':form.cleaned_data.get('cont_credit'), 
           'balanta':form.cleaned_data.get('balanta'), 
         } 
         cont_complete,created=Conturi.objects.get_or_create(**new_data) 
    else: 
     balanta_form=BalantaForm() 
     formset=ConturiInlineFormSet(instance=balanta) 
    return render_to_response('sitfin/balanta_introducere.html',{'balanta_form':balanta_form,'formset':formset}, context_instance=RequestContext(request)) 

回答

1

formset.cleaned_data是個人形式cleaned_data列表。您需要遍歷formset,併爲每一個Conturi對象:

if formset.is_valid(): 
    for form in formset: 
     cont, created=Conturi.objects.get_or_create(**form.cleaned_data) 

UPDATE:

爲了保護自己從額外的表單字段導致的錯誤,不符合模型的屬性,這是更好地明確提供參數get_or_create而不是使用**form.cleaned_data

if formset.is_valid(): 
    for form in formset: 
     data = { 
      'cont': form.cleaned_data.get('cont'), 
      'cont_debit': form.cleaned_data.get('cont_debit'), 
      'cont_credit': form.cleaned_data.get('cont_credit'), 
      'balanta': form.cleaned_data.get('balanta'), 
     } 
     cont, created = Conturi.objects.get_or_create(**data) 

它基本上是相同的過程,但現在你確切地知道哪些參數被傳遞到get_or_create

+0

感謝人,但現在我跑了另一個問題,這是關於Conturi模型的領域....我認爲這是外鍵。我編輯了這個問題。謝謝。 – Kaigara 2011-05-26 19:20:04

+1

使用'**'將字典映射到函數參數時引入錯誤。顯然,一個'DELETE'鍵在一個或所有的'deleted_data'字典中。既然這不是你模型中的一個屬性,你會得到這個錯誤。無論是手動創建參數到'get_or_create'或者改變你的表單,使'DELETE'不再被傳遞。雖然手動創建參數更冗長,但也更安全,所以這將是我推薦的方法。 – 2011-05-26 19:31:58

+0

我嘗試了一些,但我得到了上述錯誤。你給了我很好的建議,但我不確定我是否正確地選擇了正確的卡車。我想要做的是這樣的:「在窗體的」Conturi部分「上查看cont是否在數據庫上,窗體應該用輸入框中的值更新它,如果它不在數據庫中,該表單應該創建它以及相應的cont_debit或cont_credit。「 – Kaigara 2011-05-26 20:23:14

相關問題