I have been trying to add a multi page form in my Django application using the formtools wizard. I need to setup custom forms for each step. There are 2 steps in total. Here is the code that I have:
views.py
TEMPLATES = {"initial": "my_app/form_initial.html",
"final": "my_app/form_last.html"}
class ModelCreateView(SessionWizardView):
model = MyModel
template_name = "my_app/model_form.html"
file_storage =
FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'custom'))
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
my_app/model_form.html
{% extends "my_app/base.html" %}
{% block extra_css %}
{{ wizard.form.media }}
{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ wizard.management_form }}
<h1>{{ wizard }}</h1>
{% if wizard.form.forms %}
<h1>{{ wizard.form.forms }}</h1>
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
<input type="submit" value="submit"/>
</form>
{% endblock content %}
my_app/form_initial.html
<-- custom form template for step 1 -->
my_app/form_last.html
<-- custom form template for step 2 -->
if I understand it correctly, the custom form templates will replace the
{{ form }}
tag in the base template being called(my_app/model_form.html).
My problem here is that, with the current code, the my_app/form_initial.html is being called directly.
Also if I try to just include
{{ wizard.management_form }}
in my_app/form_initial.html and enclose the necessary form elements, on submit, it just reloads the current page rather than taking me to my_app/form_last.html
Please let me know what am I doing wrong here.
UPDATE: I fixed the issue with custom template by properly extending the base form template. But now when I submit on the first step, the same step page reloads rather than going to the next step. Please let me know how do I debug this?
UPDATE 2: I tried debugging more and found this, my fields are not getting validated even though the post request contains the fields, the form.is_valid()
returns false. The form.errors
says that all the fields are missing
There were 2 problems in the method that I had implemented the templates.
eg:
base_form_template.html
{% block content %}
<form style="height:inherit;" action="" method="post">
{% csrf_token %}
{{ wizard.management_form }}
{{ wizard.form.errors}}
{{ wizard.form.non_field_errors}}
{% block custom_form %}
{% endblock %}
</form>
{% endblock content %}
step1.html
{% extends "my_app/base_form_template.html" %}
<-- custom form template code goes here -->
step2.html
{% extends "my_app/base_form_template.html" %}
<-- custom form template code goes here -->
name
attribute of the input fields need to be set to wizard.form.<model_attribute>.html_name
. This was difficult to find. I had initially just set it wizard.form.<model_attribute>
and wondered why it didn't work. Did some more digging and found this. The html_name
is different as its of the format <step_name>_<field_name>
. Looking at it now it does make sense to have names like this.