DEV Community 👩‍💻👨‍💻

Cover image for Django Formset: Submit two django forms at once.
Shivam Rohilla
Shivam Rohilla

Posted on

Django Formset: Submit two django forms at once.

Hello Devs, In this Post I'm gonna show you how can we submit two django forms at once and this is also called django inline forms, for example I have two forms one is for Question and another one is for Answers, and I want a inline form, like one question and that question have four answers, ok so let's see how can we do that.

Image description

Source Code:- 
https://github.com/ShivamRohilllaa/django-formset
Enter fullscreen mode Exit fullscreen mode
Original Post:- https://www.webdevcodes.com/django/django-formset-submit-two-django-forms-at-once/
Enter fullscreen mode Exit fullscreen mode

First of all create two tables in models.py:

class Question(models.Model):
    text = models.CharField(max_length=200, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.text)

    #Reverse relationship
    def get_answers(self):
        return self.answers.all()   

class Answer(models.Model):
    text = models.CharField(max_length=200, verbose_name='Answer')
    correct = models.BooleanField()
    question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='answers')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"question {self.question.text}, answer: {self.text}. correct: {self.correct}"

Enter fullscreen mode Exit fullscreen mode

Now create modelforms in forms.py:

from django.forms.models import modelformset_factory


class QuestionsForm(forms.ModelForm):
    text = forms.CharField(label='Question', required=True)

    class Meta:
        model = Question
        fields = ['text']


AnswerFormset = modelformset_factory(
    Answer,
    fields=('text', 'correct'),
    extra=4,
    widgets={ 'text': forms.TextInput(attrs={ 'class': 'form-control','placeholder': 'Enter Answer here'}
            )
        }
)        


Enter fullscreen mode Exit fullscreen mode

import modelformset_factory then use modelformset_factory this in that form in which you want to show extra fields. for example one question have multiple answers, so we modelformset_factory in answer form

Now create views for that forms.


def add_questions(request):
    ques= QuestionsForm()
    formset = AnswerFormset(queryset=Answer.objects.none())
    if request.method=='POST':
        ques= QuestionsForm(request.POST)
        formset = AnswerFormset(request.POST)
        if ques.is_valid() and formset.is_valid():
            ques = ques.save()
            for form in formset:
                answer = form.save(commit=False)
                answer.question = ques
                answer.save() 
            return redirect('home')
    return render(request, "add-ques.html", {'ques':ques, 'formset':formset})


def home(request):
    ques = Question.objects.all()
    context = {'ques':ques}
    return render(request, 'index.html', context)


Enter fullscreen mode Exit fullscreen mode

Now render that form in your template

<form action="." method='post'>
        {% csrf_token %}
        {% for field in ques %}
        <div class="form-group">
            <label for="text">{{field.label}}:</label>
            {{field}}
        </div>
        {% endfor %}
        {% comment %} {{ques}}
        {{formset}} {% endcomment %}
        {{ formset.management_form }}
        {% for field in formset %}
        <div class="form-group mt-5 mb-5">
          <label for="text">{{field.label}}</label>
          {{field.text}}
        </div>
        {% endfor %}
        <button type="submit" class="btn btn-primary">Submit</button>
      </form>
Enter fullscreen mode Exit fullscreen mode

that's it and this is how your form look like

Image description

Image description

Source Code:- 
https://github.com/ShivamRohilllaa/django-formset
Enter fullscreen mode Exit fullscreen mode

Thank you
Shivam Rohilla Python Developer

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.