Package: django2-formtools-addons
‘Addons for Django Formtools’FeaturesAdd multiple forms to a single WizardView step (MultipleFormWizardView and subclasses)Use form wizard via JSON web API (WizardAPIView)QuickstartInstall formtools-addons:pip install django2-formtools-addonsThen use it in a project:# Every *MultipleForm* WizardView that can be imported is an equivalent of a builtin *WizardView in Django Formtools
from formtools_addons import (SessionMultipleFormWizardView, CookieMultipleFormWizardView,
                              NamedUrlSessionMultipleFormWizardView, NamedUrlCookieMultipleFormWizardView,
                              MultipleFormWizardView, NamedUrlMultipleFormWizardView)

# The WizardAPIView is also based on the builtin WizardView, but does not have the classic request-response cycle,
# since it exposes a JSON API
from formtools_addons import WizardAPIViewWizardAPIView: Example usefrom__future__importunicode_literalsfromformtools_addonsimportWizardAPIViewfrom.formsimportForm1,Form2,Form3,Form4defshow_substep_4(wizard):cleaned_data=wizard.get_cleaned_data_for_step('my-page1|my-substep-1')or{}returncleaned_data.get('some_field',None)!='some_value'classTestWizardAPIView(WizardAPIView):form_list=[("my-page1",(("my-substep-1",Form1),("my-substep-2",Form2),("my-substep-3",Form3))),("my-page2",(('my-substep-4',Form4),))]condition_dict={'my-page2|my-substep-4':show_substep_4,}form_templates={"my-page1|my-substep-1":'demo/page1_substep1.html',"my-page2|my-substep-4":'demo/page2_substep4.html',}preview_templates={"my-page1|my-substep-1":'demo/page1_substep1_preview.html',"my-page2|my-substep-4":'demo/page2_substep4_preview.html',}defrender_form(self,step,form):# Get preview template urltemplate_url=self.form_templates.get(step,None)iftemplate_urlisNone:data=form.cleaned_datareturn'<p>NO TEMPLATE: STEP:%s, DATA:%s</p>'%(step,json.dumps(data,default=self.json_encoder.default))# Load templatetemplate=get_template(template_url)# Create contextcontext=Context()context['form']=formreturntemplate.render(context)defrender_preview(self,step,form):ifnotform.is_boundornotform.is_valid():return# Get preview template urltemplate_url=self.preview_templates.get(step,None)iftemplate_urlisNone:data=form.cleaned_datareturn'<p>NO TEMPLATE: STEP:%s, DATA:%s</p>'%(step,json.dumps(data,default=self.json_encoder.default))# Load templatetemplate=get_template(template_url)# Create contextcontext=Context()context['data']=form.cleaned_dataif(form.is_boundandform.is_valid())else{}returntemplate.render(context)################################################################# testwizard/urls.pyfrom__future__importunicode_literalsfromdjango.conf.urlsimporturlfromdjango.views.decorators.csrfimportensure_csrf_cookiefrom.viewsimportTestWizardAPIViewtest_wizard=TestWizardAPIView.as_view(url_name='wizard')urlpatterns=[# Registration Wizard API URL'surl(r'^(?P<step>.+)/(?P<substep>.+)/$',ensure_csrf_cookie(test_wizard),name='wizard_step'),url(r'^(?P<step>.+)/$',ensure_csrf_cookie(test_wizard),name='wizard_step'),]MultipleFormWizardView: Example usefrom__future__importunicode_literalsfromdjangoimportformsfromdjango.shortcutsimportrender_to_responsefromformtools_addonsimportSessionMultipleFormWizardViewfrom.formsimportForm1,Form2,Form3classWizard(SessionMultipleFormWizardView):form_list=[("start",Form1),("user_info",(('account',Form2),('address',Form3)))]templates={"start":'demo/wizard-start.html',"user_info":'demo/wizard-user_info.html'}defget_template_names(self):return[self.templates[self.steps.current]]defdone(self,form_dict,**kwargs):result={}forkeyinform_dict:form_collection=form_dict[key]ifisinstance(form_collection,forms.Form):result[key]=form_collection.cleaned_dataelifisinstance(form_collection,dict):result[key]={}forsubkeyinform_collection:result[key][subkey]=form_collection[subkey].cleaned_datareturnrender_to_response('demo/wizard-end.html',{'form_data':result,})############################################################################################form=Wizard.as_view(form_list,instance_dict={'start':user,# User model instance'user_info':{'account':Account.objects.get(user=user),'address':Address.objects.get(user=user),},})Running Tests$ toxHistory0.1.0 (2016-02-01)First release on PyPI.