philgyford / django-nested-inline-formsets-example

An example of how to use Django inline formsets, each of which contains its own inline formset

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ValueError exception when trying to save nested FormSet of an empty parent Form

PaperNick opened this issue · comments

Currently, when an empty Book inline has BookImage inlines, the form raises ValueError with the following message:

save() prohibited to prevent data loss due to unsaved related object 'book'.

nested inline save valueerror

One way to handle this issue is to skip saving BookImage inlines (the nested FormSet) for Books which haven't been saved:

def save(self, commit=True):
    """
    Also save the nested formsets.
    """
    result = super().save(commit=commit)

    for form in self.forms:
        if hasattr(form, 'nested'):
            if not form.instance or form.instance._state.adding:
                # Do not save the nested formset of
                # an instance which hasn't been persisted.
                # Note: this will discard the data of
                # the nested formset and may result in data loss
                continue

            if not self._should_delete_form(form):
                form.nested.save(commit=commit)

    return result

But I don't particularly like this approach, because it results in data loss. The information about the BookImage inlines is simply discarded without warning the user.

Another approach is to catch this behavior during the validation process, but I still haven't worked that one out.

Good catch, thanks @PaperNick!

I'll try and find time to have a closer look at some point, unless you beat me to it.