Django:如何根据两个模型保存表单组

6 投票
1 回答
6610 浏览
提问于 2025-04-16 17:38

我在把一个表单集合保存到数据库时遇到了困难。我有两个模型,其中一个模型通过外键关联到另一个模型(我在Django的管理页面为Balanta模型做了一些条目):

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模型中的字段(它通过外键关联到Balanta模型),并且在下面有Balanta模型的字段。但是当我点击提交时,出现了KeyError 'data'的错误。在这个步骤我遇到了这个错误,之前也遇到过一些其他错误,比如balanta_id不能为null,或者关于管理表单的错误。

我想根据我从下拉菜单中选择的日期来保存Conturi表单集合(日期是预先填好的,但我也可以手动输入),以后在开发中我会尝试添加一个jquery来在表单中添加更多的Conturi字段,然后再把整个表单集合保存到数据库,但这离我现在的问题还远得很。

非常感谢!

1 个回答

4

看看这个链接:http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets。这个内容可以大大简化通过外键关联的用法,应该非常适合你。

你不应该像现在这样逐个处理清理后的数据,简单地用

.save()就可以了。而且我觉得你在模板中遍历表单而不是表单集有点奇怪。我现在超级困,所以不太确定。还有,当表单集不合法时,你的代码没有返回任何响应,这样会导致500错误。

基本上,你应该为Balanta模型使用一个表单,为另一个模型使用一个内联表单集。这样你就可以分两部分进行验证:if formset is valid... 和 if form is valid....

撰写回答