2011-05-14 70 views
5

我有困难的时候将表单保存到数据库。我有2个型号,一个有一个ForeignKey其他(我做了一些条目在Django管理页面巴兰塔模型):Django:如何保存基于两个模型的表单

models.py

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: 
     #ordering=['cont'] 
     verbose_name_plural="Conturi" 

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

接下来我犯了一个forms.py

from sitfin.models import Conturi, Balanta 
from django.forms import ModelForm 

class BalantaForm(ModelForm): 
    class Meta: 
     model=Balanta 

class ConturiForm(ModelForm): 
    class Meta: 
     model=Conturi 

views.py

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.formsets import formset_factory 

def conturi_index(request): 
    return render_to_response('sitfin/conturi_index.html',{'conturi_list':Conturi.objects.all()}) 

def conturi_introducere(request): 
    ConturiFormSet=formset_factory(ConturiForm) 
    if request.method=='POST': 
     #form=ConturiForm(data=request.POST) 
     conturi_formset=ConturiFormSet(request.POST, request.FILES) 
     #if form.is_valid(): 
     if conturi_formset.is_valid(): 
      for form in conturi_formset.cleaned_data: 
       balanta=Balanta(data=form['data']) 
       balanta.save() 
       cont=Conturi(cont=form['cont']) 
       cont.save() 
       return HttpResponseRedirect("sitfin/conturiok") 
    else: 
     #form=ConturiForm() 
     conturi_formset=ConturiFormSet() 
    #return render_to_response('sitfin/conturi_introducere.html',{'form':form}) 
    return render_to_response('sitfin/conturi_introducere.html',{'conturi_formset':conturi_formset}, context_instance=RequestContext(request)) 

模板

<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 

    <title>Conturi_introducere</title> 

</head> 
<body> 
    <p>BAGA CONTURILE</p> 
    <form action="" method="post">{% csrf_token %} 
     {{ conturi_formset.management_form }} 
     <table border="0"> 
      {% for cform in conturi_form %} 
      {{ cform }} 
      {% endfor %} 
     </table> 

    <p><input type="submit" value="Submit"></p> 
    </form> 
</body> 
</html> 

我管理有一种形式,是与Conturi模型领域的表单集(与外键巴兰塔模型)和巴兰塔模型,但是当现场下方我按提交我得到KeyError的'数据'。这是这一步的错误,但我得到的错误,我设法克服像balanta_id不能为空,或有关篡改management_form。

我想保存基于我从下拉选择的日期Conturi formset(日期预填充,但我也可以手动输入它)和后来在开发中我会尝试添加一个jQuery在表单中添加更多的Conturi字段,然后将所有的表单集保存到数据库中,但是它的waaaaaaay离我的问题太远了。

非常感谢!

回答

3

查看: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets 这真的简化了与外键密切相关的用例,它应该完全适合您。

你不应该像你这样迭代clean_data,一个简单的form.save()应该这样做。另外,它让我感到奇怪,你会遍历模板中的表单而不是模板中的表单集。我很困倦atm,所以我不知道。并且当formset无效时,您的代码不会返回响应。你会得到500的错误。

基本上,您应该使用Balanta模型的表单和另一个的内联表单。然后您可以执行验证分为两部分:if formset is valid ...和if form is valid. ..

+0

谢谢!所以我应该在两个单独的ifs中进行验证? – Kaigara 2011-05-17 17:44:08

+0

我做到了男人,你摇滚!根据您的答案,我设法将两种表单/表单集的数据保存在数据库中。^- ^ – Kaigara 2011-05-17 19:58:15