FormWizard inside view with proper context handling and site templating support, without having to use urls.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
######### libs.py ####################################
# This gives you the extra functionality you'll need 
######################################################
from django.contrib.formtools.wizard import FormWizard

class FormWizardSnip(FormWizard):
    def __init__(self, context):
        # Override the extra context
        self.extra_context = context

        # Call the original init
        super(FormWizardSnip, self).__init__(self._forms)

    def __call__(self, request):
        return super(FormWizardSnip, self).__call__(request)

def render_to_wizard(f, request, context):
    c = f(context=context)
    return c(request)

######## forms.py ####################################
# This is the place where the forms go
######################################################

from django import forms
from django.shortcuts import render_to_response
from webapp.libs import FormWizardSnip
from django.template import RequestContext

class testform_step1(forms.Form):
    subject = forms.CharField(max_length=100)
    sender = forms.EmailField()

class testform_step2(forms.Form):
    message = forms.CharField(widget=forms.Textarea)

class testform( FormWizardSnip ):
    # We define the form list here, rather than in the __init__() call. MUCH nicer!!!
    _forms = [CreateNewGateway_step1, CreateNewGateway_step2]

    def get_template(self, step):
        return 'wizard_step%s.html' % step

    def done(self, request, form_list):
        # Compile extra content
        o = self.extra_context
        o['form_data'] = [form.cleaned_data for form in form_list]
        
        # Build the request context
        context = RequestContext(request, o)

        return render_to_response('wizard_done.html', context_instance=context)

######## views.py ####################################
# This is the view function which your urls.py has hit
######################################################
from libs import render_to_wizard
from forms import testform

def test(request):
    # perform your application logic here (user testing etc)

    # Build the request context (this can be used by your overall site templates etc)
    context = {
        'templateOptions'       :   'etc etc'
    }

    # Call the correct parent function with the correct context
    return render_to_wizard(testform, context=context, request=request)



Thats it! I hope this helps someone!

More like this

  1. Add URL Segments to Templates by epicserve 4 years, 8 months ago
  2. Complex Form Preview by smagala 4 years, 2 months ago
  3. Ajax form with jQuery by Donn 4 years, 10 months ago
  4. Session-backed FormWizard by donspaulding 4 years, 8 months ago
  5. email_links by sansmojo 6 years ago

Comments

DimmuR (on September 13, 2010):

First of all - it's great tutorial and thanks for that.

Your _forms should be:

_forms = [testform_step1, testform_step2]

instad of :

_forms = [CreateNewGateway_step1, CreateNewGateway_step2]

Also parsing extra_context didn't work for me but i've manage to find way out by:

changing FormWizardSnip init and call functions to:

class FormWizardSnip(FormWizard):

def __init__(self, context): 
    super(FormWizardSnip, self).__init__(self._forms) 
    self.extra_context = context

def __call__(self, request, *args, **kwargs):
    kwargs = dict(self.extra_context, **kwargs )  
    return super(FormWizardSnip, self).__call__(request, *args, **kwargs)

made it work great. I hope it helps

#

(Forgotten your password?)