Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap a Django Form Wizard in a View?

This question is highly related to one that was previously asked and answered here: How wrap a FormWizard in a View?

Can someone post exact details of how they have successfully wrapped a Django Form Wizard into a view so that the login_required decorator can be used? There are numerous discussions of this topic on the internet but they all seem to be incomplete because they don't actually show how they have defined their Form Wizard class.

When I run point my browser to the view, I get the following exception:

__init__() takes exactly 1 non-keyword argument (2 given) in views.py line #108

What arguments do I pass when I instantiate my Form Wizard object such that it doesn't give me this error? If you have some sample code that works, please post it.

Here is whats in my urls.py file:

url(r'^createObject/$', views.createObjectView, name='createObject'),

Here is whats in my views.py file:

CREATE_OBJECT_FORMS = [
    ("createMyForm0", createObjectForm0),
    ("createMyForm1", createObjectForm1),
    ("createMyForm2", createObjectForm2),
    ("createMyForm3", createObjectForm3),
]

CREATE_OBJECT_TEMPLATES = {
    "createMyForm0": "myApp/form0.html",
    "createMyForm1": "myApp/form1.html",
    "createMyForm2": "myApp/form2.html",
    "createMyForm3": "myApp/form3.html",
}




@login_required
def createObjectView(request):
    # Set up the dictionary of initial data for the form
    # In this case, we are pre-filling some data from the first form only
    initial = {0: {}}

    # Create the form wizard
    form = createObjectWizard(
        [
            createObjectForm0,
            createObjectForm1,
            createObjectForm2,
            createObjectForm3,
        ], 
        initial=initial      # This is Line #108
    )

    # Call the form wizard passing through the context and the request
    return form(context=RequestContext(request), request=request)    




class createObjectWizard(SessionWizardView):
    def get_template_names(self):
        return [CREATE_OBJECT_TEMPLATES[self.steps.current]]

    def done(self, form_list, **kwargs):
        doSomethingFunction(form_list)
        return HttpResponseRedirect('/objectCreated/')
like image 573
Saqib Ali Avatar asked Dec 07 '22 09:12

Saqib Ali


1 Answers

The as_view function converts a class based view into a callable view:

myapp/views.py

from django import forms
from django.contrib.auth.decorators import login_required
from django.contrib.formtools.wizard.views import SessionWizardView
from django.template.response import TemplateResponse

class Form1(forms.Form):
    a = forms.CharField()

class Form2(forms.Form):
    b = forms.CharField()

FORMS = [("step1", Form1),
         ("step2", Form2)]

TEMPLATES = {"step1": "wizard_step.html",
             "step2": "wizard_step.html"}

class MyWizard(SessionWizardView):

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

    def done(self, form_list):
        # get data from forms
        a = self.get_cleaned_data_for_step('step1')['a']
        b = self.get_cleaned_data_for_step('step2')['b']
        # access the request as self.request
        request = self.request
        # (...)
        # return response
        return TemplateResponse(request, 'wizard_success.html', {
            'a': a,
            'b': a
        })

wizard_view = MyWizard.as_view(FORMS)

@require_login
def wrapped_wizard_view(request):
    return wizard_view(request)

myapp/templates/wizard_step.html

{% extends "base.html" %}
{% load i18n %}

{% block content %}

<form method="post">
{% include "formtools/wizard/wizard_form.html" %}
</form>

{% endblock %}

myapp/urls.py

from django.conf.urls import patterns, url

urlpatterns = patterns('myapp.views',
    url(r'^wizard/$', 'wrapped_wizard_view'),
)
like image 149
bikeshedder Avatar answered Dec 23 '22 08:12

bikeshedder