Django formsets are pretty great… once you figure out how to use them. Here is a pretty good tutorial.
I was using the inlineformset_factory function:
in this case the function automagically creates a modelform for each item. If you want to alter that form, you can create a form and send it as a keyword:
inlineformset_factory(container_model, item_model, form=item_form)
but what if you need to change the form’s save method? In my case, my model had a field that I wanted to have the system set rather than the user. So I excluded it from the form and planned to add it in the form save method. The problem was the item needs to set a foreign key to the container model. How does that foreign key get set?
The answer is the save method is called with commit=False. All I had to do was set the field and pass the unsaved object back. Like this:
class ItemForm(forms.ModelForm): class Meta: model = models.Item exclude = ('myfield',) def save(self, *args, **kwargs): # Commit is already set to false obj = super(ItemForm, self).save(*args, **kwargs) obj.myfield = 3 return obj