Skip to content

Commit

Permalink
Fixed #16597 -- Added Sphinx cross-reference metadata to the form wiz…
Browse files Browse the repository at this point in the history
…ard docs. Thanks FunkyBob for the report and jkistler for the patch.

Also, additional fixes in that document and in the WizardView docstrings.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16904 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
ramiro committed Sep 26, 2011
1 parent 3ef1762 commit 735fbcf
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 41 deletions.
16 changes: 8 additions & 8 deletions django/contrib/formtools/wizard/views.py
Expand Up @@ -124,7 +124,7 @@ def get_initkwargs(cls, form_list, initial_dict=None,
The key should be equal to the `step_name` in the `form_list` (or 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 the str of the zero based counter - if no step_names added in the
`form_list`) `form_list`)
* `instance_dict` - contains a dictionary of instance objects. This list * `instance_dict` - contains a dictionary of instance objects. This
is only used when `ModelForm`s are used. The key should be equal to is only used when `ModelForm`s are used. The key should be equal to
the `step_name` in the `form_list`. Same rules as for `initial_dict` the `step_name` in the `form_list`. Same rules as for `initial_dict`
apply. apply.
Expand Down Expand Up @@ -286,7 +286,7 @@ def post(self, *args, **kwargs):


def render_next_step(self, form, **kwargs): def render_next_step(self, form, **kwargs):
""" """
THis method gets called when the next step/form should be rendered. This method gets called when the next step/form should be rendered.
`form` contains the last/current form. `form` contains the last/current form.
""" """
# get the form instance based on the data from the storage backend # get the form instance based on the data from the storage backend
Expand Down Expand Up @@ -349,14 +349,14 @@ def get_form_instance(self, step):
""" """
Returns a object which will be passed to the form for `step` Returns a object which will be passed to the form for `step`
as `instance`. If no instance object was provied while initializing as `instance`. If no instance object was provied while initializing
the form wizard, None be returned. the form wizard, None will be returned.
""" """
return self.instance_dict.get(step, None) return self.instance_dict.get(step, None)


def get_form_kwargs(self, step=None): def get_form_kwargs(self, step=None):
""" """
Returns the keyword arguments for instantiating the form Returns the keyword arguments for instantiating the form
(or formset) on given step. (or formset) on the given step.
""" """
return {} return {}


Expand Down Expand Up @@ -404,7 +404,7 @@ def process_step_files(self, form):
def render_revalidation_failure(self, step, form, **kwargs): def render_revalidation_failure(self, step, form, **kwargs):
""" """
Gets called when a form doesn't validate when rendering the done Gets called when a form doesn't validate when rendering the done
view. By default, it changed the current step to failing forms step view. By default, it changes the current step to failing forms step
and renders the form. and renders the form.
""" """
self.storage.current_step = step self.storage.current_step = step
Expand All @@ -428,7 +428,7 @@ def get_all_cleaned_data(self):
""" """
Returns a merged dictionary of all step cleaned_data dictionaries. Returns a merged dictionary of all step cleaned_data dictionaries.
If a step contains a `FormSet`, the key will be prefixed with formset If a step contains a `FormSet`, the key will be prefixed with formset
and contain a list of the formset' cleaned_data dictionaries. and contain a list of the formset cleaned_data dictionaries.
""" """
cleaned_data = {} cleaned_data = {}
for form_key in self.get_form_list(): for form_key in self.get_form_list():
Expand Down Expand Up @@ -532,15 +532,15 @@ def get_context_data(self, form, **kwargs):


def render(self, form=None, **kwargs): def render(self, form=None, **kwargs):
""" """
Returns a ``HttpResponse`` containing a all needed context data. Returns a ``HttpResponse`` containing all needed context data.
""" """
form = form or self.get_form() form = form or self.get_form()
context = self.get_context_data(form, **kwargs) context = self.get_context_data(form, **kwargs)
return self.render_to_response(context) return self.render_to_response(context)


def done(self, form_list, **kwargs): def done(self, form_list, **kwargs):
""" """
This method muss be overrided by a subclass to process to form data This method must be overridden by a subclass to process to form data
after processing all steps. after processing all steps.
""" """
raise NotImplementedError("Your %s class has not defined a done() " raise NotImplementedError("Your %s class has not defined a done() "
Expand Down
78 changes: 45 additions & 33 deletions docs/ref/contrib/formtools/form-wizard.txt
Expand Up @@ -90,9 +90,11 @@ Creating a ``WizardView`` class
------------------------------- -------------------------------


The next step is to create a The next step is to create a
:class:`django.contrib.formtools.wizard.view.WizardView` subclass. You can :class:`django.contrib.formtools.wizard.views.WizardView` subclass. You can
also use the :class:`SessionWizardView` or :class:`CookieWizardView` class also use the :class:`SessionWizardView` or :class:`CookieWizardView` classes
which preselects the wizard storage backend. which preselect the backend used for storing information during execution of the
wizard (as their names indicate, server-side sessions and browser cookies
respectively).


.. note:: .. note::


Expand Down Expand Up @@ -148,7 +150,8 @@ Next, you'll need to create a template that renders the wizard's forms. By
default, every form uses a template called default, every form uses a template called
:file:`formtools/wizard/wizard_form.html`. You can change this template name :file:`formtools/wizard/wizard_form.html`. You can change this template name
by overriding either the :attr:`~WizardView.template_name` attribute or the by overriding either the :attr:`~WizardView.template_name` attribute or the
:meth:`~WizardView.get_template_names()` method, which is documented below. :meth:`~WizardView.get_template_names()` method, which is documented in the
:class:`~django.views.generic.base.TemplateResponseMixin` documentation.
This hook also allows you to use a different template for each form. This hook also allows you to use a different template for each form.


This template expects a ``wizard`` object that has various items attached to This template expects a ``wizard`` object that has various items attached to
Expand All @@ -171,7 +174,7 @@ it:
* ``all`` -- A list of all steps of the wizard. * ``all`` -- A list of all steps of the wizard.


You can supply additional context variables by using the You can supply additional context variables by using the
:meth:`~FormWizard.get_context_data` method of your :class:`FormWizard` :meth:`~WizardView.get_context_data` method of your :class:`WizardView`
subclass. subclass.


Here's a full example template: Here's a full example template:
Expand Down Expand Up @@ -213,7 +216,7 @@ Hooking the wizard into a URLconf
--------------------------------- ---------------------------------


Finally, we need to specify which forms to use in the wizard, and then Finally, we need to specify which forms to use in the wizard, and then
deploy the new :class:`WizardView` object a URL in the ``urls.py``. The deploy the new :class:`WizardView` object at an URL in the ``urls.py``. The
wizard's :meth:`as_view` method takes a list of your wizard's :meth:`as_view` method takes a list of your
:class:`~django.forms.Form` classes as an argument during instantiation:: :class:`~django.forms.Form` classes as an argument during instantiation::


Expand Down Expand Up @@ -262,9 +265,10 @@ Advanced ``WizardView`` methods


.. method:: WizardView.get_form_initial(step) .. method:: WizardView.get_form_initial(step)


Returns a dictionary which will be passed to the form for ``step`` as Returns a dictionary which will be passed as the
``initial``. If no initial data was provided while initializing the :attr:`~django.forms.Form.initial` argument when instantiating the Form
form wizard, an empty dictionary should be returned. instance for step ``step``. If no initial data was provided while
initializing the form wizard, an empty dictionary should be returned.


The default implementation:: The default implementation::


Expand All @@ -283,9 +287,13 @@ Advanced ``WizardView`` methods


.. method:: WizardView.get_form_instance(step) .. method:: WizardView.get_form_instance(step)


Returns an object which will be passed to the form for ``step`` as This method will be called only if a :class:`~django.forms.ModelForm` is
``instance``. If no instance object was provided while initializing used as the form for step ``step``.
the form wizard, None be returned.
Returns an :class:`~django.db.models.Model` object which will be passed as
the :attr:`~django.forms.ModelForm.instance` argument when instantiating the
ModelForm for step ``step``. If no instance object was provided while
initializing the form wizard, ``None`` will be returned.


The default implementation:: The default implementation::


Expand Down Expand Up @@ -358,9 +366,9 @@ Advanced ``WizardView`` methods
.. method:: WizardView.process_step(form) .. method:: WizardView.process_step(form)


This method gives you a way to post-process the form data before the data This method gives you a way to post-process the form data before the data
gets stored within the storage backend. By default it just passed the gets stored within the storage backend. By default it just returns the
form.data dictionary. You should not manipulate the data here but you can ``form.data`` dictionary. You should not manipulate the data here but you
use the data to do some extra work if needed (e.g. set storage extra data). can use it to do some extra work if needed (e.g. set storage extra data).


Default implementation:: Default implementation::


Expand All @@ -370,9 +378,9 @@ Advanced ``WizardView`` methods
.. method:: WizardView.process_step_files(form) .. method:: WizardView.process_step_files(form)


This method gives you a way to post-process the form files before the This method gives you a way to post-process the form files before the
files gets stored within the storage backend. By default it just passed files gets stored within the storage backend. By default it just returns
the ``form.files`` dictionary. You should not manipulate the data here the ``form.files`` dictionary. You should not manipulate the data here
but you can use the data to do some extra work if needed (e.g. set storage but you can use it to do some extra work if needed (e.g. set storage
extra data). extra data).


Default implementation:: Default implementation::
Expand All @@ -382,8 +390,8 @@ Advanced ``WizardView`` methods


.. method:: WizardView.render_revalidation_failure(step, form, **kwargs) .. method:: WizardView.render_revalidation_failure(step, form, **kwargs)


When the wizard thinks, all steps passed it revalidates all forms with the When the wizard thinks all steps have passed it revalidates all forms with
data from the backend storage. the data from the backend storage.


If any of the forms don't validate correctly, this method gets called. If any of the forms don't validate correctly, this method gets called.
This method expects two arguments, ``step`` and ``form``. This method expects two arguments, ``step`` and ``form``.
Expand All @@ -399,9 +407,9 @@ Advanced ``WizardView`` methods


.. method:: WizardView.get_form_step_data(form) .. method:: WizardView.get_form_step_data(form)


This method fetches the form data from and returns the dictionary. You This method fetches the data from the ``form`` Form instance and returns the
can use this method to manipulate the values before the data gets stored dictionary. You can use this method to manipulate the values before the data
in the storage backend. gets stored in the storage backend.


Default implementation:: Default implementation::


Expand All @@ -420,8 +428,8 @@ Advanced ``WizardView`` methods


.. method:: WizardView.render(form, **kwargs) .. method:: WizardView.render(form, **kwargs)


This method gets called after the get or post request was handled. You can This method gets called after the GET or POST request has been handled. You
hook in this method to, e.g. change the type of http response. can hook in this method to, e.g. change the type of HTTP response.


Default implementation:: Default implementation::


Expand Down Expand Up @@ -467,7 +475,7 @@ Handling files
To handle :class:`~django.forms.FileField` within any step form of the wizard, To handle :class:`~django.forms.FileField` within any step form of the wizard,
you have to add a :attr:`file_storage` to your :class:`WizardView` subclass. you have to add a :attr:`file_storage` to your :class:`WizardView` subclass.


This storage will temporarilyy store the uploaded files for the wizard. The This storage will temporarily store the uploaded files for the wizard. The
:attr:`file_storage` attribute should be a :attr:`file_storage` attribute should be a
:class:`~django.core.files.storage.Storage` subclass. :class:`~django.core.files.storage.Storage` subclass.


Expand All @@ -482,9 +490,9 @@ Conditionally view/skip specific steps


.. attribute:: WizardView.condition_dict .. attribute:: WizardView.condition_dict


The :meth:`~WizardView.as_view` accepts a ``condition_dict`` argument. You can pass a The :meth:`~WizardView.as_view` method accepts a ``condition_dict`` argument.
dictionary of boolean values or callables. The key should match the steps You can pass a dictionary of boolean values or callables. The key should match
name (e.g. '0', '1'). the steps names (e.g. '0', '1').


If the value of a specific step is callable it will be called with the If the value of a specific step is callable it will be called with the
:class:`WizardView` instance as the only argument. If the return value is true, :class:`WizardView` instance as the only argument. If the return value is true,
Expand All @@ -493,7 +501,7 @@ the step's form will be used.
This example provides a contact form including a condition. The condition is This example provides a contact form including a condition. The condition is
used to show a message form only if a checkbox in the first step was checked. used to show a message form only if a checkbox in the first step was checked.


The steps are defined in a ``forms.py``:: The steps are defined in a ``forms.py`` file::


from django import forms from django import forms


Expand Down Expand Up @@ -546,10 +554,14 @@ As you can see, we defined a ``show_message_form_condition`` next to our
How to work with ModelForm and ModelFormSet How to work with ModelForm and ModelFormSet
=========================================== ===========================================


The WizardView supports :class:`~django.forms.ModelForm` and .. attribute:: WizardView.instance_dict
:class:`~django.forms.ModelFormSet`. Additionally to the ``initial_dict``,
the :meth:`~WizardView.as_view` method takes a ``instance_dict`` argument WizardView supports :class:`~django.forms.ModelForm` and
with a list of instances for the ``ModelForm`` and ``ModelFormSet``. :class:`~django.forms.ModelFormSet`. Additionally to the ``initial_dict``, the
:meth:`~WizardView.as_view` method takes a ``instance_dict`` argument that
should contain instances of ``ModelForm`` and ``ModelFormSet``. Similarly to
:attr:`~WizardView.initial_dict`, thos dictionary key values should be equal to
the `step_name` in the `form_list`.


Usage of NamedUrlWizardView Usage of NamedUrlWizardView
=========================== ===========================
Expand Down

0 comments on commit 735fbcf

Please sign in to comment.