Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 779
DanH Avatar asked Oct 26 '25 11:10

DanH


2 Answers

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)
like image 148
trecouvr Avatar answered Oct 29 '25 06:10

trecouvr


The form itself never know what index it has in the formset, much like any given list and its containing objects.

Unless you tell it to know it, so in your case first you have to tell the .save() to accept an additional parameter.

class MyForm(forms.Form):
   def save(self, index):
     #do save magix

Then loop over your formset when validating and pass the form its index.

for index, form in enumerate(my_formset):
   form.save(index)
like image 27
Henrik Andersson Avatar answered Oct 29 '25 07:10

Henrik Andersson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!