Можете ли вы создать родительский объект и список дочерних объектов в одной и той же форме - PullRequest
0 голосов
/ 19 мая 2019

Я новичок в 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()

Вот эскиз того, как я ожидал, что он будет выглядеть

Заранее спасибо! Ура!

1 Ответ

0 голосов
/ 19 мая 2019

Вы можете использовать ModelForm для note (поскольку будет только 1 примечание) и InlineFormSet для item (так как вы разрешите несколько). Вам не нужно сохранять note до items - вы можете сохранить их по тому же запросу.

Динамическое добавление / удаление items требует javascript и не будет рассмотрено в этом ответе, однако должно быть достаточно легко понять, что django ожидает получить.

Итак, прежде всего вам нужно создать ModelForm:

forms.py:

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

Мы собираемся использовать inlineformset_factory для создания InlineFormSet для 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. Это уменьшит некоторые грубые части моделей, так как вам не нужно беспокоиться об их уникальности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...