[Fixed]-Combining two forms in one Django view

39👍

Formsets are the way to do it in django.

First add default value for Poll.pub_date field:

class Poll(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published', default=timezone.now)

Then make forms a bit simpler:

class PollForm(forms.ModelForm):
    class Meta:
        model = Poll
        fields = ('question_text', )

class ChoiceForm(forms.ModelForm):
    class Meta:
        model = Choice
        fields = ('choice_text',)

Add formset support to your view:

from django.forms.formsets import formset_factory

def add_poll(request):
    ChoiceFormSet = formset_factory(ChoiceForm, extra=3,
                                    min_num=2, validate_min=True)
    if request.method == 'POST':
        form = PollForm(request.POST)
        formset = ChoiceFormSet(request.POST)
        if all([form.is_valid(), formset.is_valid()]):
            poll = form.save()
            for inline_form in formset:
                if inline_form.cleaned_data:
                    choice = inline_form.save(commit=False)
                    choice.question = poll
                    choice.save()
            return render(request, 'polls/index.html', {})
    else:
        form = PollForm()
        formset = ChoiceFormSet()

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

And finally your template:

<form method="post">

    {% csrf_token %}

    <table>
        {{ form }}
        {{ formset }}
    </table>

    <button>Add</button>

</form>

Leave a comment