0

I have a Django 1.6 form wizard that contains 5 forms. I want each of the forms to have access to the values of the fields in all previous forms.

I have defined a get_context_data method in views.py and it seems to do what it should. Here is my views.py

from django.shortcuts import render
from django.shortcuts import render_to_response
from django.contrib.formtools.wizard.views import SessionWizardView
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
import pdb

class CalcWizard(SessionWizardView):

    # Override template_name
    template_name = 'calc/forms.html'

    # Define a __name__ property on the wizard.
    # We do this because a number of Django decorators
    # raise an AttributeError when you use them to 
    # decorate an instance, complaining they cant find __name__
    @property
    def __name__(self):
        return self.__class__.__name__

    def get_context_data(self, form, **kwargs):
        context = super(CalcWizard, self).get_context_data(form=form, **kwargs)
        if self.steps.current >= 0:
            data_0 = self.get_cleaned_data_for_step('0') # zero indexed
            context.update({'data_0':data_0})
        if self.steps.current >= 1:
            data_1 = self.get_cleaned_data_for_step('1')
            context.update({'data_1':data_1})
        if self.steps.current >= 2:
            data_2 = self.get_cleaned_data_for_step('2')
            context.update({'data_2':data_2})
        return context

    def done(self, form_list, **kwargs):
        # This is not done yet
        return render_to_response('calc/forms.html', {
            'form_data': [form.cleaned_data for form in form_list],
        })

However, I don't understand how to access the context data in my forms.

This is a part of my forms.py:

class DeliveryForm(forms.Form):

    costs = forms.DecimalField(\
        max_digits=16, \
        decimal_places=2, \
        label=_(u'Materialkostnad (kr)'), \
        localize=True, \
        validators=[MinValueValidator(0)])
    amount = forms.DecimalField(\
        max_digits=16, \
        decimal_places=2, \
        label=_(u'Mängd/Antal (kvm)'), \
        localize=True, \
        validators=[MinValueValidator(0)])
    CHOICES=[(0,'BLC inomhus'), (1,'BLC utomhus'), \
        (2,'BLC externt inomhus'), (3,'BLC externt utomhus')]
    blc_inventory = forms.ChoiceField(\
        choices=CHOICES, \
        widget=forms.RadioSelect(), \
        label=_(u'Var vill du lagra ditt material?'))
    ...
    ...
    ...
    ...

    def __init__(self, *args, **kwargs):
        super(DeliveryForm, self).__init__(*args, **kwargs)
        if kwargs ??? is not None:
            form.costs=???

Here is parts of my urls.py

urlpatterns = patterns('',

    url(r'^admin/filebrowser/', include(site.urls)),
    url(r'^grappelli/', include('grappelli.urls')),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^calc/$', CalcWizard.as_view([\
        ConstructionForm,\
        DeliveryForm,\
        KitningForm,\
        CarryinginForm,\
        ResultForm]
    )),
)

How do I access context data in my forms?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Reino Wallin
  • 1
  • 1
  • 2

1 Answers1

0

Your description is a little short, but I am assuming that you get_context_data is in a view, since you say that it does what it is supposed to.

Your form will only be able to access this context once you instantiate it in the view having the context. So you could pass the context to your form like:

form = DeliveryForm(ctx=context)

In your forms __init__ you can check if it is there to use like this:

def __init__(self, *args, **kwargs):
    super(DeliveryForm, self).__init__(*args, **kwargs)
    ctx = kwargs.get('ctx', None)
    if ctx is not None:
        form.s_costs=ctx['costs']

In case of a view using something the likes of the Wizard, there is a get_form_kwargs where you can set the right context for the form. Something the likes of:

def get_form_kwargs(self, step):
    kwargs = {}
    if step == 1:
        kwargs['foo'] = 'bar'
    return kwargs

From within the form you can now access the kwarg['foo'].

jfunez
  • 397
  • 6
  • 23
  • Thank you for your reply. I have updated my post to be more specific. – Reino Wallin Sep 11 '14 at 09:24
  • Where, more precisely, should i add the instantiation, form = DeliveryForm(ctx=context), in my view? – Reino Wallin Sep 11 '14 at 09:36
  • Sorry about the delay. Since you're using the Wizard, you can use the get_form_kwargs from the wizard to pass the right context to your form. [See the docs](https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/#django.contrib.formtools.wizard.views.WizardView.get_form_kwargs) Just check the step for the right value to pass to the form. – Pan Pitolek Sep 15 '14 at 10:19