Search code examples
djangodjango-formsdjango-1.6

How can a form within a formset know it's index within the formset?


I have a basic Form subclass with a formset generated such as:

MyFormset = formset_factory(
    MyForm,
    extra=5,
    max_num=5,
)

I would like to be able to access the index of the form from within the form.save() and form.__init__ methods.


Solution

  • You can subclass BaseFormSet to pass the index to the form:

    from django.forms.formsets import BaseFormSet
    
    class BaseMyFormSet(BaseFormSet):
        def add_fields(self, form, index):
            """A hook for adding extra fields on to each form instance."""
            super(BaseMyFormSet, self).add_fields(form, index)
            # here call a custom method or perform any other required action
            form.set_index(index)
    
    MyFormset = formset_factory(
        MyForm,
        formset=BaseMyFormSet,
        extra=5,
        max_num=5,
    )
    

    This method will be called for each created form in the formset, you may perform whatever operation you need.

    To get the index on save, I see two possibilities:

    1) You use an hidden field that you set in the set_index method above

    class MyForm(forms.Form):
        formset_index = forms.IntegerField(widget=forms.HiddenInput())
    
        def set_index(self, index):
            self.fields['formset_index'].initial = index
    

    2) You can use enumerate

    # definition
    class MyForm(forms.Form):
        def save(self, index):
        ...
    
    # save
    for index, form in enumerate(my_formset):
       form.save(index)