[Answer]-Django: Handling several forms in one submit, using class based views?

1👍

✅

Urls:

url(r'^edit/(?P<model1_pk>\d+)/(?P<model2_pk>\d+)/$', EditBaseForm.as_view(), name='edit'),

View:

class EditBaseForm(TemplateView):
    template_name = 'some_edit.html'

    def dispatch(self, request, *args, **kwargs):
        self.object1 = get_object_or_404(SomeModel1, pk=kwargs.get('model1_pk'))
        self.object2 = get_object_or_404(SomeModel2, pk=kwargs.get('model2_pk'))
        # and so on

        return super(EditBaseForm, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(EditBaseForm, self).get_context_data(**kwargs)
        if not (context.get('form1') and context.get('form2')):  # actually you can check only first of them
            context['form1'] = FormClass1(instance=self.object1)
            context['form2'] = FormClass2(instance=self.object2)

        return context

    def post(self, request, *args, **kwargs):
        form1 = FormClass1(request.POST, request.FILES, instance=self.object1)
        form2 = FormClass2(request.POST, request.FILES, instance=self.object2)

        if form1.is_valid() and form2.is_valid():
            return self.form_valid(form1, form2)
        else:
            return self.form_invalid(form1, form2)

    def form_valid(self, form1, form2):
        form1.save()
        form2.save()

        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form1, form2):
        return self.render_to_response(
            self.get_context_data(
                form1=form1,
                form2=form2,
            )
        )

    def get_success_url(self):
        return reverse('some_app:some_url')

Template:

<form method="post">{% csrf_token %}
    {{ form1.as_p }}
    {{ form2.as_p }}

    <input type="submit" value="Submit" />
</form>

Leave a comment