[Django] #21667: Allow dynamic form classes with WizardView

23 views
Skip to first unread message

Django

unread,
Dec 24, 2013, 4:41:03 PM12/24/13
to django-...@googlegroups.com
#21667: Allow dynamic form classes with WizardView
-------------------------------+--------------------
Reporter: nickname123 | Owner: nobody
Type: New feature | Status: new
Component: Generic views | Version: 1.6
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
The WizardView does not currently support dynamic form classes without
overriding the entire get_form method.

My mixin below demonstrates an easy way to make this convenient. I needed
this functionality to support using modelform_factory at runtime to
accommodate logic that varies depending on choices made previously in the
wizard. A simple use case is to support dynamic "required" fields.

{{{
class WizardDynamicFormClassMixin(object):
def get_form_class(self, step):
return self.form_list[step]

def get_form(self, step=None, data=None, files=None):
"""
This method was copied from the base Django 1.6 wizard class in
order to
support a callable `get_form_class` method which allows dynamic
modelforms.

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.
"""
if step is None:
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),
})
if issubclass(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))
elif issubclass(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))
return self.get_form_class(step)(**kwargs)
}}}

This is a simple demonstration of usage:

{{{
def get_form_class(self, step):
if step == STEP_FOO:
try:
choice_foo =
self.get_cleaned_data_for_step(STEP_FOO)["choice_foo"]
except KeyError:
pass
else:
# get_wizard_form_class() would return a model
form with fields
# that depend on the value of "choice"
return
ModelFoo(choice=choice_foo).get_wizard_form_class()
return super(WizardFoo, self).get_form_class(step)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/21667>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 24, 2013, 5:50:27 PM12/24/13
to django-...@googlegroups.com
#21667: Allow dynamic form classes with WizardView
-----------------------------------+--------------------------------------

Reporter: nickname123 | Owner: nobody
Type: New feature | Status: new
Component: contrib.formtools | Version: 1.6
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------------+--------------------------------------
Changes (by aaugustin):

* needs_docs: => 0
* component: Generic views => contrib.formtools
* needs_tests: => 0
* needs_better_patch: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/21667#comment:1>

Django

unread,
Mar 28, 2014, 8:33:26 PM3/28/14
to django-...@googlegroups.com
#21667: Allow dynamic form classes with WizardView
-----------------------------------+------------------------------------

Reporter: nickname123 | Owner: nobody
Type: New feature | Status: new
Component: contrib.formtools | Version: 1.6
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------------+------------------------------------
Changes (by timo):

* stage: Unreviewed => Accepted


Comment:

Seems like it could be a useful hook.

--
Ticket URL: <https://code.djangoproject.com/ticket/21667#comment:2>

Django

unread,
Apr 13, 2014, 12:36:16 PM4/13/14
to django-...@googlegroups.com
#21667: Allow dynamic form classes with WizardView
-----------------------------------+------------------------------------

Reporter: nickname123 | Owner: nobody
Type: New feature | Status: new
Component: contrib.formtools | Version: 1.6
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------------+------------------------------------
Changes (by Fabio Caritas Barrionuevo da Luz <bnafta@…>):

* cc: bnafta@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/21667#comment:3>

Django

unread,
Oct 18, 2014, 3:49:59 PM10/18/14
to django-...@googlegroups.com
#21667: Allow dynamic form classes with WizardView
-----------------------------------+------------------------------------
Reporter: nickname123 | Owner: nobody
Type: New feature | Status: closed
Component: contrib.formtools | Version: 1.6
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-----------------------------------+------------------------------------
Changes (by gchp):

* status: new => closed
* resolution: => fixed


Comment:

formtools has been extracted into its own repository
(​https://github.com/django/django-formtools/). Because of this, the issue
tracking for this package has been moved to GitHub issues. I'm going to
close this ticket, but I've created a GitHub issue to replace it where the
conversation can continue: ​https://github.com/django/django-
formtools/issues/16. Thanks!

--
Ticket URL: <https://code.djangoproject.com/ticket/21667#comment:4>

Reply all
Reply to author
Forward
0 new messages