madtyn madtyn - 3 years ago 335
Python Question

Django formtools wizard produces blank page (No error returned)

I'm trying to use the formwizard in formtools package with no success (I was able to do it when the package was inside Django in earlier versions).

The only response I got is:

[23/Jan/2016 11:06:50]"GET /registration/wizard HTTP/1.1" 200 13729


and a blank page. No errors in browser or Eclipse console.

There's no way of googling without errors. Please help.

Thanks in advance

What did I do?

Firstly, I installed the formtools package with pip:

django-formtools==1.0
Django==1.8.3


Following the instructions of the official docs:


  1. Define form classes

    registration/forms.py

    class StepForm1(forms.Form):
    first_field = forms.CharField(max_length=100)
    second_field = forms.CharField()

    class StepForm2(forms.Form):
    message = forms.CharField(widget=forms.Textarea)

  2. Create WizardView

    registration/views.py

    TEST_TEMPLATES = {"test_step_1": "registration/test_step1.html", "test_step_2": "registration/test_step2.html", }

    from formtools.wizard.views import SessionWizardView

    class WizardTest(SessionWizardView):
    template_name = 'registration/test_wizard.html'

    # Return templates for each step
    def get_templates_name(self):
    return [TEST_TEMPLATES[self.steps.current]]

    # Method called when all is done
    def done(self, form_list, **kwargs):

    # return HttpResponseRedirect('/url-to-redirect-to/')

    # We return the final template with the info
    return render_to_response('test_done.html', {
    'form_data':[form.cleaned_data for form in form_list],
    })

    # THESE METHODS BELOW ARE NOT NEEDED, BUT COMMENTED FOR FUTURE USE

    # Not strictly needed. Returns data for a step
    # or None if form is not valid
    # def get_cleaned_data_for_step(self, step):
    # return None

    # Form data postprocessing in a concrete wizard step
    # def process_step(self, form):
    # return self.get_form_step_data(form)

    # Handles value from a step before storing them into wizard
    # def get_form_step_data(self, form):
    # return form.data

  3. Create the templates

    registration/test_step1.html

    <h1>Two fields form</h1>
    <input id="first_field" name="first_field">
    <input id="second_field" name="second_field">


    registration/test_step2.html

    <h1>Message form</h1>
    <input id="message" name="message">


    registration/test_wizard.html

    {% extends "person/alumnos.html" %}
    {% load i18n %}

    {% block head %}
    {{ wizard.form.media }}
    {% endblock head %}

    {% block content %}
    <p>{% trans "Step {{wizard.steps.step1}} of {{wizard.steps.count}}" %}</p>

    <form action="" method="post">
    {% csrf_token %}

    {{ wizard.management_form }}

    {% if wizard.form.forms %}
    {{ wizard.form.management_form }}
    {% for form in wizard.form.forms %}
    {{form}}
    {% endfor %}
    {% else %}
    {{ wizard.form }}
    {% endif %}

    {% if wizard.steps.prev %}
    <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "Beginning" %}</button>
    <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "Previous step" %}</button>
    {% endif %}
    <input type="submit" value="submit"/>

    </form>

    {% endblock %}

  4. Add 'formtools' to my INSTALLED_APPS

    settings.py

    DJANGO_APPS = (
    # Default Django apps:
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'formtools', # <===== HERE

    # Useful template tags:
    # 'django.contrib.humanize',

    # Admin panel and documentation:
    'django.contrib.admin',
    # 'django.contrib.admindocs',
    )

    # Apps specific for this project go here.
    LOCAL_APPS = (
    'person',
    'registration',
    'teaching',
    'utils',
    )

    # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
    INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS

  5. Point my URLconf at your WizardView as_view() method.



registration/urls.py

from registration.forms import StepForm1, StepForm2
TEST_FORMS = [("test_step_1", StepForm1), ("test_step_2", StepForm2), ]

from registration.views import WizardTest

# I tried in two ways, none of them worked

urlpatterns = patterns('',
url(r'^wizard$', WizardTest.as_view(TEST_FORMS), name='wizard_test'),
url(r'^wizard2$', views.wizard, name='wizard_test'),
)


For the second way...

registration/views.py

def wizard(request):
return WizardTest.as_view(TEST_FORMS)(request)

Answer Source

I found my error. I typed badly the method name for getting the templates. It's not

get_templates_name(self)

but

get_template_names(self)

It wasn't getting any templates, but when returning to server it was answering with HTTP 200 OK, because it didn't found any error.

I also found that my templates for every step should extend the main wizard template in order to work correctly. With the 'done' template is not necessary.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download