(References:
- Django formtools done function not executed
- https://django-formtools.readthedocs.io/en/latest/_modules/formtools/wizard/views.html#WizardView
- https://django-formtools.readthedocs.io/en/latest/wizard.html#wizardview-advanced-methods )
I am trying to do the same thing. The steps are working and individual form data able to get, but after the submit button is clicked and final form is submitted, I expect all three form data to be submitted at once and the done function has to process that but it is not happening. I am not able to find the reason why. Because of policy I can't share the code but putting a dummy code here and logic what I am implementing. Kindly please direct. Following is my code,
(This is a Edit Form I am trying to create, in each form init method is also overrided for initial data wrt pk, this all is working not an issue)
done.html
{% extends CURRENT_TEMPLATE %}
{% load static %}
{% block content %}
Hi you are watching done.html
{{ data }}
{% endblock content %}
form.html
{% extends CURRENT_TEMPLATE %}
{% load i18n %}
{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form.as_table }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
{% if wizard.steps.next %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.next }}">{% trans "next step" %}</button>
{% endif %}
{% if not wizard.steps.next %}
<button type="submit" value="{% trans "submit" %}">{% trans "Submit" %}</button>
{% endif %}
</form>
{% endblock %}
Forms.py
from django import forms
class RouteEditForm1(ModelForm):
field1 = forms.CharField(max_length=100)
class Meta:
model = MainModel
fields = ['field2','field3']
class RouteEditForm2(ModelForm):
class Meta:
model = MainModel
fields = ['field4','field5']
class RouteEditForm3(ModelForm):
class Meta:
model = MainModel
fields = ['field6','field7']
Views.py
from django.shortcuts import render
from .forms import RouteEditForm1, RouteEditForm2, RouteEditForm3
from formtools.wizard.views import SessionWizardView
# Create your views here.
class RouteEditView(SessionWizardView):
template_name = "form.html"
form_list = [RouteEditForm1, RouteEditForm2, RouteEditForm3]
# following functions are in order of their call
# This is working
def get_form(self, step=None, data=None, files=None):
print("\n ----------------- inside get_form step ",self.steps.current)
form = super().get_form(step, data, files)
# determine the step if not given
if step is None:
step = self.steps.current
if step == '1':
form.user = self.request.user
return form
# This is working
def get_form_kwargs(self, step):
print("\n ----------------- inside get_form_kwargs ", step)
kwargs = super(RouteEditView, self).get_form_kwargs()
# print("self.request ", self.request)
kwargs['request'] = self.request
kwargs['pk'] = self.kwargs['pk']
# print("get_form_kwargs kwargs ", kwargs)
return kwargs
# This is working
def get_form_initial(self, step):
print("\n ----------------- inside get_form_initial step ", step)
if 'pk' in self.kwargs:
try:
pk = self.kwargs['pk']
if pk is None:
print("\n ---------get_form_initial-------- pk is none ")
else:
pk = Getid(self.request, pk)
print("\n ---------get_form_initial-------- pk is ", pk)
except Exception as e:
print("Exception in get_form_initial ", e)
import traceback
traceback.print_exc()
messages.warning(
self.request, "Unable to process your request.")
return {}
else:
return self.initial_dict.get(step, {})
# This is working
def get_form_instance(self, step):
print("\n ----------------- inside get_form_instance step ", step)
# step 0: user form
if 'pk' in self.kwargs:
pk = self.kwargs['pk']
pk = Getid(self.request, pk)
# The default implementation
return self.instance_dict.get(step, None)
# This is working
def get_context_data(self, form, **kwargs):
print("\n ----------------- get_context_data step ",self.steps.current)
try:
# print("\n inside get_context_data step try", self.steps.current)
context = super(RouteEditView, self).get_context_data(
form=form, **kwargs)
context.update({'another_var': "sdfsdfsdfsdfsdfsdfsdf"})
type = "Edit"
head = "Route Details"
context.update(
{'type': type, 'head': head, "request": self.request})
except Exception as e:
print("Exception in get_context_data ", e)
import traceback
traceback.print_exc()
return context
# This is not Working
def done(self, form_list, form_dict, **kwargs):
print("\n ----------------- done step ", self.steps.current)
try:
form_dict2 = self.get_all_cleaned_data()
# print("\n done method ", form_dict2)
form_data = [form.cleaned_data for form in form_list]
return render(self.request, 'done.html', {'data':form_data})
except Exception as e:
print("Exception in done ", e)
import traceback
traceback.print_exc()
And also after submitting the final form at last step the page is redirected to step 1 again. Why?