Django:如何保存基于两个模型的表单集
我在将表单集保存到数据库时遇到困难。我有 2 个模型,一个模型有另一个模型的外键(我在 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 不能为空,或者有关篡改 management_form 的错误。
我想根据我从下拉列表中选择的日期保存 Conturi 表单集(日期已预先填充,但我也可以手动输入),稍后在开发中我将尝试添加一个 jquery 来添加更多 Conturi表单中的字段,然后将所有表单集保存在数据库中,但这离我的问题太远了。
非常感谢!
I am having difficult times saving a formset to the database. I have 2 models, one having a ForeignKey to the other(I made some entries for Balanta model in Django admin page):
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)
next i made a 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
and the 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))
and the template:
<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>
I manage to have a form which is a formset with the fields in Conturi model(with foreign key to Balanta model) and below the field in Balanta model but when i press submit i get KeyError 'data'. This is the error at this step but i get errors which i managed to overcome like balanta_id cannot be null, or something about tampering with the management_form.
I want to save the Conturi formset based on the date i'm choosing from the drop-down(the date is prepopulated but i could also enter it by hand) and later in the development i will try to add a jquery to add more Conturi fields in the form and after that to save all the formset in the database, but it's waaaaaaay too far from my problem.
Thank You very much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看看这个:
http://docs.djangoproject.com/en/dev/主题/表单/modelforms/#inline-formsets
这确实简化了与外键相关的用例,这应该非常适合您。
您不应该像您那样迭代 clean_data ,一个简单的 form.save() 应该可以做到这一点。另外,令我感到奇怪的是,您会迭代表单而不是模板中的表单集。我非常困,所以我不知道。当表单集无效时,您的代码不会返回响应。您将收到 500 错误。
基本上,您应该为 Balanta 模型使用一个表单,为另一个模型使用内联表单集。然后您可以分两部分进行验证:
if formset is valid
... 和if form is valid.
..Check this out:
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets
This really simplifies the related by foreign-keys use case which should perfectly fit you.
You shouldn't iterate over the cleaned_data like you do, a simple form.save() should do it. Also, it strikes me as odd that you would iterate over the form rather than the formset in the template. I'm super sleepy atm, so I dunno. And your code does not return a response when the formset isn't valid. You'll get a 500 error for that.
Basically you should use a form for the Balanta model and a inline formset for the other one. Then you can carry out the validation in two parts:
if formset is valid
... andif form is valid.
..