I created the ticket containing the wizard proposal, it includes new
cleaned up version that offers a lot more flexibility...

http://code.djangoproject.com/ticket/3218

On 12/27/06, Honza Kr l <[EMAIL PROTECTED]> wrote:
So,
a little example with dynamic forms, I hope you don't mind
pseudo-code, I don't feel like writing a working standalone example
and I cannot publish my application (its in Czech anyway ;) )

urls.py:

urlpatterns = patterns('some.app.views',
  (r'wizard/$', 'my_wizard' ),
)

some/app/views.py:
from django import newforms as forms
from django.contrib.formtools import wizard

# we always have to supply at least one form
class FirstForm( forms.Form ):
   item_list = forms.MultipleChoiceField( choices=[ (1,'ONE'), ( 2, 'TWO) ] )

# function that will generate a second form for us dynamically:
def get_second_form( items ):
  # second form contains only labels for items selected in FirstForm
  class SecondForm( forms.Form ):
    def __init__( self, **kwargs ):
      super( SecondForm, self ).__init__( **kwargs )
      for i in items:
         self.fields['label_%s' % i ] = forms.CharField( max_length=100 )
  return SecondForm

# our wizard
class LabelManyWizard( wizard.Wizard ):
  # after submitting the first form, create the second and append it
to form_list
  def process_step( self, request, form, step ):
    if step == 0:
      form.full_clean()
      self.form_list.append( get_second_form( form.clean_data['item_list'] ) )
    super(LabelManyWizard, self ).process_step( request, form, step )

  # when both forms are validly filled, do what you always wanted to do
  def done( self, request, form_list ):
    first, second = form_list
    first.full_clean()
    second.full_clean()
    for i in first.clean_data['item_list']:
       print "Label for item %s is %s" % ( i, second.clean_data[
'label_%s' % i ])
    return HttpresponseRedirect( '/' )


# a little wrapper function - we could put the LabelManyWizard(
[FirstForm] ) into urls as a callable,
# but since it modifies its form_list it wouldn't work, hence this
little work around
# (this is only neccessary for dynamic wizards)

def my_wizard( request ):
  wiz = LabelManyWizard( [FirstForm] )
  return wiz( request )

-------------  DONE -------------------

in order for this to work, you will need patch from ticket #3193 -
that is needed to pass the values from FirstForm.item_list because
normal as_hidden() wouldn't work for MultipleChoiceField...

looking forward to any comments
Honza


On 12/26/06, Honza Kr l <[EMAIL PROTECTED]> wrote:
> Hello all,
>
> I got bored during the holiday, so I put together a simple
> implementation of django.contrib.formtools.wizard...
>
> Features:
>  all data are kept in POST, nothing is stored on the server (this is
> simply not very good for file uploads, but should be OK for the
> majority)
>
>   security_hash from preview.py (by adrian) is used to ensure that
> previously submitted data didn't change (if they have, returns to the
> step in question), successful validation is only done once
>
>   old data are stored as individual fields not pickled by step
>
>   process_step() is called after successful validation of every step
> or after verifying the step's hash.. it is not meant to change
> something in the DB, it is meant as a hook to change the wizard's
> state (for example after processing step 1, generate form for step 2).
> That's also why it is called every time a form is submitted for all
> submitted steps (except the current one if its invalid)
>
>   done() is THE method to override, it receives list of form instances
> with valid data corresponding to the form_list, and the request
> object, its output is returned directly...
>
> Bugs:
>   there is no (or very little) way of introducing your own logic or
> overriding some defaults (for example there is no way to supply the
> step number vie URL), this will change (see TODO)
>
>   no documentation so far - I first want to make sure people are OK
> with the state of things before I start doing some. However if someone
> needs to know more than is written here to give it a try, let me
> know...
>
> Usage:
>   1) subclass it and supply a done() method, that will taje request
> and a list of form instances with valid data
>   2) into urls enter:
>    ( r'SOMETHING', MyWizard( [MyForm1, MyForm2, ...] ) ),
>   3) supply a template (default is test.html so far, or override it in
> get_template() ) taht looks like this:
>  <form action="." method="POST">
>  FORM( {{ step }}): {{ form }}
>
>  previous_fields: {{ previous_fields }}
>
>  <input type="submit">
>  </form>
>
>   4) report bugs and enhancement requests here or to me personally
>
> I am looking forward for any feedback
> Thanks
> Honza
>
> On 12/20/06, rassilon <[EMAIL PROTECTED]> wrote:
> >
> > One slight modification, there was debugging code left in, which I've
> > now fixed.
> >
> >
> > > > >
> >
>
>
> --
> Honza Kr l
> E-Mail: [EMAIL PROTECTED]
> ICQ#:   107471613
> Phone:  +420 606 678585
>
>


--
Honza Kr l
E-Mail: [EMAIL PROTECTED]
ICQ#:   107471613
Phone:  +420 606 678585



--
Honza Kr l
E-Mail: [EMAIL PROTECTED]
ICQ#:   107471613
Phone:  +420 606 678585

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django 
developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to