Django:如何保存基于两个模型的表单 [英] Django: How to save a formset based on two models

查看:115
本文介绍了Django:如何保存基于两个模型的表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在数据库中保存表单时遇到困难。我有2个模型,一个有一个ForeignKey到另一个(我在Django管理页面中为Balanta模型做了一些条目):



models.py

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

class Meta:
order = ['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



<$来自django.http import的p $ p> 导入HttpResponseRedirect $ d
从django.shortcuts导入get_object_or_404,render_to_response
从django.template导入RequestContext
从sitfin.models导入Balanta,Conturi
来自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():
如果conturi_formset.is_valid():
在conturi_formset.cleaned_data中的
balanta = Balanta(data = form ['data'])
balanta.save()
cont = Conturi(con​​t = form [' cont'])
cont.save()
return HttpResponseRedirect(sitfin / conturiok)
else:
#form = ConturiForm()
conturi_formset = ConturiFormSet )
#return render_to_response('sitfin / conturi_introducere.html',{'form':form})
返回render_to_response('sitfin / conturi_introducere.html',{'conturi_formset':conturi_formset},context_instance = RequestContext(request))

模板

 < html> 
< head>
< meta http-equiv =content-typecontent =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 =submitvalue =Submit>< / p>
< / form>
< / body>
< / html>

我设法拥有一个表单,它是Contric模型中的字段(用外键Balanta模型)和在Balanta模型的字段下面,但当我按提交我得到KeyError'数据'。这是这个步骤的错误,但我收到错误,我设法克服,如balanta_id不能为null,或有关篡改management_form的一些。



我想保存根据我从下拉菜单中选择的日期(该日期是预先填写的,但是我也可以手动输入),而后来在开发中,我将尝试添加一个jquery来添加更多的Conturi字段的形式,之后,将所有的formset保存在数据库中,但是waaaaaaay离我的问题太远了。



非常感谢!

解决方案

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



你不应该像你一样迭代clean_data,一个si mple form.save()应该这样做。另外,它打破了我的奇怪,你会迭代在窗体而不是模板中的formset。我是超级困倦的大脑,所以我不知道。而且当formset无效时你的代码不会返回一个响应。你会得到一个500错误。



基本上,您应该为Balanta模型使用一个表单,另一个应使用内联表单。那么你可以在两个部分中执行验证:如果formset有效,则如果formset有效 ...和如果表单有效。 ..


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!

解决方案

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... and if form is valid...

这篇关于Django:如何保存基于两个模型的表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆