您能以一种相同的形式创建父对象和子对象列表吗

时间:2019-05-19 14:38:13

标签: django django-models django-forms

我是django的新手,但仍在学习其全部潜力。我有两个模型,一个是父项(GoodsReceivedNote),另一个是该项的项目(一对多)。我意识到普通的ModelForm在这里不起作用,因为我希望用户能够输入父对象以及子对象的详细信息。

我查看了InlineFormSets,但据我所知,我需要先创建父对象,然后将其分配给我的孩子。 还查看了此链接:http://sayhelloworld.co/create-parent-child-model-objects-in-one-form-with-django/他们如何使用日期来获取最近的父对象并将其添加到子对象中,这似乎不是最好的方法

GoodsReceivedNote.py

class Goodsreceivednote(models.Model):
    GOODS_INWARDS = 'INWARDS'
    GOODS_REJECTED = 'REJECTED'
    NOTE_TYPES = (
        (GOODS_INWARDS, GOODS_INWARDS),
        (GOODS_REJECTED, GOODS_REJECTED),
    )
    rec_note_id = models.CharField(primary_key=True, max_length=20)  
    note_date = models.DateField()  
    type = models.CharField(choices= NOTE_TYPES, max_length=15, default=GOODS_INWARDS)  

Items.py

class Goodsreceiveitem(models.Model):
    received_item_id = models.CharField(primary_key=True, max_length=255) 
    rec_note_id = models.ForeignKey(Goodsreceivednote, models.PROTECT) 
    item_id = models.ForeignKey(Inventory, models.PROTECT) 
    item_qty = models.IntegerField()

Here is a Sketch of how i expected it to look like

先谢谢了!干杯!

1 个答案:

答案 0 :(得分:0)

您可以将ModelForm用于note(因为只有1个音符),InlineFormSet用于item(因为您将允许多个音符)。您无需在note之前保存items-您可以在相同的请求下保存它们。

动态添加/删除items需要使用javascript,并且不会在此答案中讨论,但是应该很容易理解django希望收到的内容。

因此,首先需要创建ModelForm

forms.py:

class NoteForm(forms.ModelForm):
    class Meta:
        model = Goodsreceivednote
        fields = '__all__'

我们将使用inlineformset_factoryInlineFormSet创建items。保存项目时,我们必须向外部字段提供父注释。

views.py:

from django.forms import inlineformset_factory

from .models import Goodsreceivednote, Goodsreceiveitem
from .forms import NoteForm

def note_view(request):
    # Create formset based on our parent model and child model. We are going to allow up to 3 items in form. 
    NoteFormSet = inlineformset_factory(Goodsreceivednote, Goodsreceiveitem, fields='__all__', extra=3)

    # generate form and formset
    form = NoteForm(request.POST or None, request.FILES or None)
    formset = NoteFormSet(request.POST or None, request.FILES or None)

    if form.is_valid() and formset.is_valid():
        note = form.save()
        for form in formset.forms:
            item = form.save(commit=False)
            item.rec_note_id = note
            item.save()

    return render(request, 'formset.html', {'form': form, 'formset': formset})

formset.html:

<form method="post">
    {% csrf_token %}

    {{ form.as_p }}

    {{ formset.as_p }}

    <button type="submit">submit</button>
</form>

您还没有在模型中指定主键-它们将自动生成为AutoField。这将减少模型的一些粗糙部分,因为您不必担心它们的独特性。