Django: Как сохранить набор форм на основе двух моделей - PullRequest
5 голосов
/ 14 мая 2011

У меня трудные времена при сохранении набора форм в базе данных. У меня есть 2 модели, одна с ForeignKey, а другая (я сделал несколько записей для модели Balanta на странице администратора 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 (с внешним ключом к модели Balanta) и под полем в модели Balanta, но когда я нажимаю submit, я получаю KeyError 'data'. Это ошибка на этом шаге, но я получаю ошибки, которые мне удалось преодолеть, например, balanta_id не может быть нулевым, или что-то не так с подделкой management_form.

Я хочу сохранить набор форм Conturi на основе даты, которую я выбираю из раскрывающегося списка (дата предварительно заполнена, но я также мог бы ввести ее вручную), и позже в процессе разработки я попытаюсь добавить jquery к добавьте в форму дополнительные поля Conturi и после этого сохраните все формы в базе данных, но это слишком далеко от моей проблемы.

Большое спасибо!

1 Ответ

3 голосов
/ 15 мая 2011

Проверьте это: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets Это действительно упрощает связанный случай использования внешних ключей, который должен идеально подходить вам.

Вы не должны перебирать cleaned_data, как это делаете вы; простая form.save () должна это делать. Кроме того, мне кажется странным, что вы будете перебирать форму, а не форму в шаблоне. Я супер сонный атм, поэтому я не знаю. И ваш код не возвращает ответ, когда набор форм недействителен. Вы получите 500 ошибок за это.

В основном вам следует использовать форму для модели Balanta и встроенный набор форм для другой. Затем вы можете выполнить проверку в двух частях: if formset is valid ... и if form is valid. ..

...