Methods

WizardView

This method is used within urls.py to create unique wizardview
instances for every request. We need to override this method because
we add some kwargs which are needed to make the wizardview usable.

113
114
115
116
117
118
119
120
121

@classonlymethoddefas_view(cls,*args,**kwargs):""" This method is used within urls.py to create unique wizardview instances for every request. We need to override this method because we add some kwargs which are needed to make the wizardview usable. """initkwargs=cls.get_initkwargs(*args,**kwargs)returnsuper(WizardView,cls).as_view(**initkwargs)

View

@classonlymethoddefas_view(cls,**initkwargs):""" Main entry point for a request-response process. """# sanitize keyword argumentsforkeyininitkwargs:ifkeyincls.http_method_names:raiseTypeError("You tried to pass in the %s method name as a ""keyword argument to %s(). Don't do that."%(key,cls.__name__))ifnothasattr(cls,key):raiseTypeError("%s() received an invalid keyword %r. as_view ""only accepts arguments that are already ""attributes of the class."%(cls.__name__,key))defview(request,*args,**kwargs):self=cls(**initkwargs)ifhasattr(self,'get')andnothasattr(self,'head'):self.head=self.getself.request=requestself.args=argsself.kwargs=kwargsreturnself.dispatch(request,*args,**kwargs)# take name and docstring from classupdate_wrapper(view,cls,updated=())# and possible attributes set by decorators# like csrf_exempt from dispatchupdate_wrapper(view,cls.dispatch,assigned=())returnview

WizardView

This method gets called by the routing engine. The first argument is
`request` which contains a `HttpRequest` instance.
The request is stored in `self.request` for later use. The storage
instance is stored in `self.storage`.
After processing the request using the `dispatch` method, the
response gets updated by the storage engine (for example add cookies).

defdispatch(self,request,*args,**kwargs):""" This method gets called by the routing engine. The first argument is `request` which contains a `HttpRequest` instance. The request is stored in `self.request` for later use. The storage instance is stored in `self.storage`. After processing the request using the `dispatch` method, the response gets updated by the storage engine (for example add cookies). """# add the storage engine to the current wizardview instanceself.prefix=self.get_prefix(*args,**kwargs)self.storage=get_storage(self.storage_name,self.prefix,request,getattr(self,'file_storage',None))self.steps=StepsHelper(self)response=super(WizardView,self).dispatch(request,*args,**kwargs)# update the response (e.g. adding cookies)self.storage.update_response(response)returnresponse

View

79
80
81
82
83
84
85
86
87

defdispatch(self,request,*args,**kwargs):# Try to dispatch to the right method; if a method doesn't exist,# defer to the error handler. Also defer to the error handler if the# request method isn't on the approved list.ifrequest.method.lower()inself.http_method_names:handler=getattr(self,request.method.lower(),self.http_method_not_allowed)else:handler=self.http_method_not_allowedreturnhandler(request,*args,**kwargs)

This method must be overridden by a subclass to process to form data
after processing all steps.

569
570
571
572
573
574
575

defdone(self,form_list,**kwargs):""" This method must be overridden by a subclass to process to form data after processing all steps. """raiseNotImplementedError("Your %s class has not defined a done() ""method, which is required."%self.__class__.__name__)

WizardView

This method handles GET requests.
If a GET request reaches this point, the wizard assumes that the user
just starts at the first step or wants to restart the process.
The data of the wizard will be resetted before rendering the first step.

242
243
244
245
246
247
248
249
250
251
252

defget(self,request,*args,**kwargs):""" This method handles GET requests. If a GET request reaches this point, the wizard assumes that the user just starts at the first step or wants to restart the process. The data of the wizard will be resetted before rendering the first step. """self.storage.reset()# reset the current step to the first step.self.storage.current_step=self.steps.firstreturnself.render(self.get_form())

defget_all_cleaned_data(self):""" Returns a merged dictionary of all step cleaned_data dictionaries. If a step contains a `FormSet`, the key will be prefixed with 'formset-' and contain a list of the formset cleaned_data dictionaries. """cleaned_data={}forform_keyinself.get_form_list():form_obj=self.get_form(step=form_key,data=self.storage.get_step_data(form_key),files=self.storage.get_step_files(form_key))ifform_obj.is_valid():ifisinstance(form_obj.cleaned_data,(tuple,list)):cleaned_data.update({'formset-%s'%form_key:form_obj.cleaned_data})else:cleaned_data.update(form_obj.cleaned_data)returncleaned_data

Returns the cleaned data for a given `step`. Before returning the
cleaned data, the stored values are revalidated through the form.
If the data doesn't validate, None will be returned.

478
479
480
481
482
483
484
485
486
487
488
489
490

defget_cleaned_data_for_step(self,step):""" Returns the cleaned data for a given `step`. Before returning the cleaned data, the stored values are revalidated through the form. If the data doesn't validate, None will be returned. """ifstepinself.form_list:form_obj=self.get_form(step=step,data=self.storage.get_step_data(step),files=self.storage.get_step_files(step))ifform_obj.is_valid():returnform_obj.cleaned_datareturnNone

ContextMixin

Constructs the form for a given `step`. If no `step` is defined, the
current step will be determined automatically.
The form will be initialized using the `data` argument to prefill the
new form. If needed, instance or queryset (for `ModelForm` or
`ModelFormSet`) will be added too.

defget_form(self,step=None,data=None,files=None):""" Constructs the form for a given `step`. If no `step` is defined, the current step will be determined automatically. The form will be initialized using the `data` argument to prefill the new form. If needed, instance or queryset (for `ModelForm` or `ModelFormSet`) will be added too. """ifstepisNone:step=self.steps.current# prepare the kwargs for the form instance.kwargs=self.get_form_kwargs(step)kwargs.update({'data':data,'files':files,'prefix':self.get_form_prefix(step,self.form_list[step]),'initial':self.get_form_initial(step),})ifissubclass(self.form_list[step],forms.ModelForm):# If the form is based on ModelForm, add instance if available# and not previously set.kwargs.setdefault('instance',self.get_form_instance(step))elifissubclass(self.form_list[step],forms.models.BaseModelFormSet):# If the form is based on ModelFormSet, add queryset if available# and not previous set.kwargs.setdefault('queryset',self.get_form_instance(step))returnself.form_list[step](**kwargs)

Returns a dictionary which will be passed to the form for `step`
as `initial`. If no initial data was provied while initializing the
form wizard, a empty dictionary will be returned.

367
368
369
370
371
372
373

defget_form_initial(self,step):""" Returns a dictionary which will be passed to the form for `step` as `initial`. If no initial data was provied while initializing the form wizard, a empty dictionary will be returned. """returnself.initial_dict.get(step,{})

Returns a object which will be passed to the form for `step`
as `instance`. If no instance object was provied while initializing
the form wizard, None will be returned.

375
376
377
378
379
380
381

defget_form_instance(self,step):""" Returns a object which will be passed to the form for `step` as `instance`. If no instance object was provied while initializing the form wizard, None will be returned. """returnself.instance_dict.get(step,None)

This method returns a form_list based on the initial form list but
checks if there is a condition method/value in the condition_list.
If an entry exists in the condition list, it will call/read the value
and respect the result. (True means add the form, False means ignore
the form)
The form_list is always generated on the fly because condition methods
could use data from other (maybe previous forms).

defget_form_list(self):""" This method returns a form_list based on the initial form list but checks if there is a condition method/value in the condition_list. If an entry exists in the condition list, it will call/read the value and respect the result. (True means add the form, False means ignore the form) The form_list is always generated on the fly because condition methods could use data from other (maybe previous forms). """form_list=SortedDict()forform_key,form_classinsix.iteritems(self.form_list):# try to fetch the value from condition list, by default, the form# gets passed to the new list.condition=self.condition_dict.get(form_key,True)ifcallable(condition):# call the value if needed, passes the current instance.condition=condition(self)ifcondition:form_list[form_key]=form_classreturnform_list

Returns the prefix which will be used when calling the actual form for
the given step. `step` contains the step-name, `form` the form which
will be called with the returned prefix.
If no step is given, the form_prefix will determine the current step
automatically.

354
355
356
357
358
359
360
361
362
363
364

defget_form_prefix(self,step=None,form=None):""" Returns the prefix which will be used when calling the actual form for the given step. `step` contains the step-name, `form` the form which will be called with the returned prefix. If no step is given, the form_prefix will determine the current step automatically. """ifstepisNone:step=self.steps.currentreturnstr(step)

Creates a dict with all needed parameters for the form wizard instances.
* `form_list` - is a list of forms. The list entries can be single form
classes or tuples of (`step_name`, `form_class`). If you pass a list
of forms, the wizardview will convert the class list to
(`zero_based_counter`, `form_class`). This is needed to access the
form for a specific step.
* `initial_dict` - contains a dictionary of initial data dictionaries.
The key should be equal to the `step_name` in the `form_list` (or
the str of the zero based counter - if no step_names added in the
`form_list`)
* `instance_dict` - contains a dictionary whose values are model
instances if the step is based on a ``ModelForm`` and querysets if
the step is based on a ``ModelFormSet``. The key should be equal to
the `step_name` in the `form_list`. Same rules as for `initial_dict`
apply.
* `condition_dict` - contains a dictionary of boolean values or
callables. If the value of for a specific `step_name` is callable it
will be called with the wizardview instance as the only argument.
If the return value is true, the step's form will be used.

@classmethoddefget_initkwargs(cls,form_list=None,initial_dict=None,instance_dict=None,condition_dict=None,*args,**kwargs):""" Creates a dict with all needed parameters for the form wizard instances. * `form_list` - is a list of forms. The list entries can be single form classes or tuples of (`step_name`, `form_class`). If you pass a list of forms, the wizardview will convert the class list to (`zero_based_counter`, `form_class`). This is needed to access the form for a specific step. * `initial_dict` - contains a dictionary of initial data dictionaries. The key should be equal to the `step_name` in the `form_list` (or the str of the zero based counter - if no step_names added in the `form_list`) * `instance_dict` - contains a dictionary whose values are model instances if the step is based on a ``ModelForm`` and querysets if the step is based on a ``ModelFormSet``. The key should be equal to the `step_name` in the `form_list`. Same rules as for `initial_dict` apply. * `condition_dict` - contains a dictionary of boolean values or callables. If the value of for a specific `step_name` is callable it will be called with the wizardview instance as the only argument. If the return value is true, the step's form will be used. """kwargs.update({'initial_dict':initial_dictorkwargs.pop('initial_dict',getattr(cls,'initial_dict',None))or{},'instance_dict':instance_dictorkwargs.pop('instance_dict',getattr(cls,'instance_dict',None))or{},'condition_dict':condition_dictorkwargs.pop('condition_dict',getattr(cls,'condition_dict',None))or{}})form_list=form_listorkwargs.pop('form_list',getattr(cls,'form_list',None))or[]computed_form_list=SortedDict()assertlen(form_list)>0,'at least one form is needed'# walk through the passed form listfori,forminenumerate(form_list):ifisinstance(form,(list,tuple)):# if the element is a tuple, add the tuple to the new created# sorted dictionary.computed_form_list[six.text_type(form[0])]=form[1]else:# if not, add the form with a zero based counter as unicodecomputed_form_list[six.text_type(i)]=form# walk through the new created list of formsforforminsix.itervalues(computed_form_list):ifissubclass(form,formsets.BaseFormSet):# if the element is based on BaseFormSet (FormSet/ModelFormSet)# we need to override the form variable.form=form.form# check if any form contains a FileField, if yes, we need a# file_storage added to the wizardview (by subclassing).forfieldinsix.itervalues(form.base_fields):if(isinstance(field,forms.FileField)andnothasattr(cls,'file_storage')):raiseNoFileStorageConfigured("You need to define 'file_storage' in your ""wizard view in order to handle file uploads.")# build the kwargs for the wizardview instanceskwargs['form_list']=computed_form_listreturnkwargs

Returns the next step after the given `step`. If no more steps are
available, None will be returned. If the `step` argument is None, the
current step will be determined automatically.

492
493
494
495
496
497
498
499
500
501
502
503
504

defget_next_step(self,step=None):""" Returns the next step after the given `step`. If no more steps are available, None will be returned. If the `step` argument is None, the current step will be determined automatically. """ifstepisNone:step=self.steps.currentform_list=self.get_form_list()key=form_list.keyOrder.index(step)+1iflen(form_list.keyOrder)>key:returnform_list.keyOrder[key]returnNone

Returns the previous step before the given `step`. If there are no
steps available, None will be returned. If the `step` argument is
None, the current step will be determined automatically.

506
507
508
509
510
511
512
513
514
515
516
517
518

defget_prev_step(self,step=None):""" Returns the previous step before the given `step`. If there are no steps available, None will be returned. If the `step` argument is None, the current step will be determined automatically. """ifstepisNone:step=self.steps.currentform_list=self.get_form_list()key=form_list.keyOrder.index(step)-1ifkey>=0:returnform_list.keyOrder[key]returnNone

Returns the index for the given `step` name. If no step is given,
the current step will be used to get the index.

520
521
522
523
524
525
526
527

defget_step_index(self,step=None):""" Returns the index for the given `step` name. If no step is given, the current step will be used to get the index. """ifstepisNone:step=self.steps.currentreturnself.get_form_list().keyOrder.index(step)

Returns a list of template names to be used for the request. Must return
a list. May not be called if render_to_response is overridden.

135
136
137
138
139
140
141
142
143
144
145

defget_template_names(self):""" Returns a list of template names to be used for the request. Must return a list. May not be called if render_to_response is overridden. """ifself.template_nameisNone:raiseImproperlyConfigured("TemplateResponseMixin requires either a definition of ""'template_name' or an implementation of 'get_template_names()'")else:return[self.template_name]

Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.

36
37
38
39
40
41
42
43
44

def__init__(self,**kwargs):""" Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things. """# Go through keyword arguments, and either save their values to our# instance, or raise an error.forkey,valueinsix.iteritems(kwargs):setattr(self,key,value)

This method handles POST requests.
The wizard will render either the current step (if form validation
wasn't successful), the next step (if the current step was stored
successful) or the done view (if no more steps are available)

defpost(self,*args,**kwargs):""" This method handles POST requests. The wizard will render either the current step (if form validation wasn't successful), the next step (if the current step was stored successful) or the done view (if no more steps are available) """# Look for a wizard_goto_step element in the posted data which# contains a valid step name. If one was found, render the requested# form. (This makes stepping back a lot easier).wizard_goto_step=self.request.POST.get('wizard_goto_step',None)ifwizard_goto_stepandwizard_goto_stepinself.get_form_list():returnself.render_goto_step(wizard_goto_step)# Check if form was refreshedmanagement_form=ManagementForm(self.request.POST,prefix=self.prefix)ifnotmanagement_form.is_valid():raiseValidationError(_('ManagementForm data is missing or has been tampered.'),code='missing_management_form',)form_current_step=management_form.cleaned_data['current_step']if(form_current_step!=self.steps.currentandself.storage.current_stepisnotNone):# form refreshed, change current stepself.storage.current_step=form_current_step# get the form for the current stepform=self.get_form(data=self.request.POST,files=self.request.FILES)# and try to validateifform.is_valid():# if the form is valid, store the cleaned data and files.self.storage.set_step_data(self.steps.current,self.process_step(form))self.storage.set_step_files(self.steps.current,self.process_step_files(form))# check if the current step is the last stepifself.steps.current==self.steps.last:# no more steps, render done viewreturnself.render_done(form,**kwargs)else:# proceed to the next stepreturnself.render_next_step(form)returnself.render(form)

This method gets called when all forms passed. The method should also
re-validate all steps to prevent manipulation. If any form don't
validate, `render_revalidation_failure` should get called.
If everything is fine call `done`.

defrender_done(self,form,**kwargs):""" This method gets called when all forms passed. The method should also re-validate all steps to prevent manipulation. If any form don't validate, `render_revalidation_failure` should get called. If everything is fine call `done`. """final_form_list=[]# walk through the form list and try to validate the data again.forform_keyinself.get_form_list():form_obj=self.get_form(step=form_key,data=self.storage.get_step_data(form_key),files=self.storage.get_step_files(form_key))ifnotform_obj.is_valid():returnself.render_revalidation_failure(form_key,form_obj,**kwargs)final_form_list.append(form_obj)# render the done view and reset the wizard before returning the# response. This is needed to prevent from rendering done with the# same data twice.done_response=self.done(final_form_list,**kwargs)self.storage.reset()returndone_response

This method gets called when the current step has to be changed.
`goto_step` contains the requested step to go to.

319
320
321
322
323
324
325
326
327
328

defrender_goto_step(self,goto_step,**kwargs):""" This method gets called when the current step has to be changed. `goto_step` contains the requested step to go to. """self.storage.current_step=goto_stepform=self.get_form(data=self.storage.get_step_data(self.steps.current),files=self.storage.get_step_files(self.steps.current))returnself.render(form)

This method gets called when the next step/form should be rendered.
`form` contains the last/current form.

303
304
305
306
307
308
309
310
311
312
313
314
315
316

defrender_next_step(self,form,**kwargs):""" This method gets called when the next step/form should be rendered. `form` contains the last/current form. """# get the form instance based on the data from the storage backend# (if available).next_step=self.steps.nextnew_form=self.get_form(next_step,data=self.storage.get_step_data(next_step),files=self.storage.get_step_files(next_step))# change the stored current stepself.storage.current_step=next_stepreturnself.render(new_form,**kwargs)

Gets called when a form doesn't validate when rendering the done
view. By default, it changes the current step to failing forms step
and renders the form.

433
434
435
436
437
438
439
440

defrender_revalidation_failure(self,step,form,**kwargs):""" Gets called when a form doesn't validate when rendering the done view. By default, it changes the current step to failing forms step and renders the form. """self.storage.current_step=stepreturnself.render(form,**kwargs)

Returns a response, using the `response_class` for this
view, with a template rendered with the given context.
If any keyword arguments are provided, they will be
passed to the constructor of the response class.

119
120
121
122
123
124
125
126
127
128
129
130
131
132

defrender_to_response(self,context,**response_kwargs):""" Returns a response, using the `response_class` for this view, with a template rendered with the given context. If any keyword arguments are provided, they will be passed to the constructor of the response class. """response_kwargs.setdefault('content_type',self.content_type)returnself.response_class(request=self.request,template=self.get_template_names(),context=context,**response_kwargs)