djangodjango-formsformsetinline-formset

Inline formset returns empty list on save?


When I try to save my inline formset it just returns an empty list and no changes are reflected in the database. I have tried doing it with no option and commit=False but they both have the same result. I know there is data because I printed the formset as a table, and I know it is valid because the property is_valid() method returns true. Here is the code:

def edit(request):
    if request.method == 'POST':
        print(request.POST)
        form = TombstoneForm(request.POST)
        print(form.is_valid())
        t = form.save(commit=False)
        t.edit_date = datetime.now()
        t.user_editor = request.user
        t.save()
        print(t)
        formset_construct = inlineformset_factory(Tombstone, Tank, form=TombstoneForm)
        formset = formset_construct(request.POST)
        print("Passed the inline formset")
        print(formset.as_table())
        print(formset.is_valid())
        l = formset.save()
        print(l)
    return render(request, 'main.html')

Solution

  • So I believe I have found the source of my problem and a workaround. The problem was occuring in the BaseModelFormSet class in this method:

        def save_existing_objects(self, commit=True):
            self.changed_objects = []
            self.deleted_objects = []
            if not self.initial_forms:
                return []
    
            saved_instances = []
            forms_to_delete = self.deleted_forms
            for form in self.initial_forms:
                obj = form.instance
                # If the pk is None, it means either:
                # 1. The object is an unexpected empty model, created by invalid
                #    POST data such as an object outside the formset's queryset.
                # 2. The object was already deleted from the database.
                if obj.pk is None:
                    continue
                if form in forms_to_delete:
                    self.deleted_objects.append(obj)
                    self.delete_existing(obj, commit=commit)
                elif form.has_changed():
                    self.changed_objects.append((obj, form.changed_data))
                    saved_instances.append(self.save_existing(form, obj, commit=commit))
                    if not commit:
                        self.saved_forms.append(form)
            return saved_instances
    

    The problem was occuring in:

    if obj.pk is None:
        continue
    

    Where it was always hitting continue, so my solution has just been to save the individual form data instead of the formset data:

            for form in formset:
                val = form.save(commit=False)
                val.Vessel = t
                val.save()