简体   繁体   中英

Setting Formset Initial Within a Django Formwizard

I'm currently trying to set the initial variable of my formset within a Django formwizard. However, instead of setting these initial variables at the beginning of the form wizard process, I want them to be dynamically created using the data from the previous step in the form wizard.

Using the get_initial_form method, I'm able to dynamically set the initial variable of only the first form in my formset. I would like to dynamically set all the forms within the formset. Is this possible?

VIEWS.PY

 class ContactWizard(SessionWizardView):
    def get_context_data(self, form, **kwargs):
            context = super(ContactWizard, self).get_context_data(form=form, **kwargs)
            if int(self.steps.current) == 1:
                    context.update({'foo': self.get_cleaned_data_for_step('0')})
            return context

    def get_form_initial(self, step, **kwargs):
            initial = self.initial_dict.get(step, {})
            if int(step) == 1:
                    form_class = self.form_list[step]
                    num_of_dates =  self.get_cleaned_data_for_step(str(int(step) - 1))['date'].split(',')
                    form_class.extra = len(num_of_dates)-1

                    initial.update({'slots': 4})
            return super(ContactWizard, self).get_form_initial(step)

    def get_template_names(self):
            return [TEMPLATES[self.steps.current]]

    def done(self, form_list, **kwargs):
            print 'testing'
            return HttpResponseRedirect('main/home.html')

URLS.PY

   url(r'^schedule/date/$', views.ContactWizard.as_view([ScheduleDate, formset_factory(ScheduleEventForm)]), name='schedule_date'),

FORMS.PY

 class ScheduleEventForm(forms.Form):
    time = forms.TimeField(label='Time', widget=forms.TextInput(attrs={'class': 'form-control time_entry_field'}))
    slots = forms.IntegerField(label='Slots', widget=forms.TextInput(attrs={'class': 'form-control slot_field'}))
    date = forms.CharField(label='', widget = forms.HiddenInput())
    class Meta:
            fields = ('time','slots')

I'm not sure that setting extra in get_form_initial is the right place to do that. Looking at what calls get_form_initial , namely get_form , you might be better off setting extra in get_form_kwargs , since the return of that will be used in the generation of the form class.

I've come by this question, looking for my own answers on how to set the initial value for a field in a formset. If I attempt to update initial at all, I end up with no initial forms in the formset and a crash. Doing interactive debugging, it's almost like it's expecting initial to be a list of dicts, one for each form in the set.

After some further investigation, it would seem that if you want to set an initial for a field in a formset, you need to pass back an array of dicts, with an entry for each expected extra. This actually seems to be a behaviour in the BaseModelFormSet (see _construct_form ) and BaseFormSet , though BaseFormSet handles the error better if a specific entry can not be found (at least for 1.10, anyway).

So, once you have determined your extra value, you need to populate a list with the same dict for as many entries as required by the extra value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM