Search code examples
djangodjango-formsinline-formset

Django inline_formset with can_delete=True and can_order=True doesn't work


I have a form with models and foreign key modes represented as inline formsets. I'm having a helluva time saving the ordered formsets. In fact, every time I try to delete one, it gets multiplied.

in forms.py:

class PublicationForm(ModelForm):
    class Meta:
        model = Publication
        fields = ['title']

SectionFormSet = inlineformset_factory(Publication, Section, can_delete=True, can_order=True, extra=2)

and in views.py:

if publication_form.is_valid():
    pub = publication_form.save(commit=False)
    section_formset = SectionFormSet(request.POST, instance=pub, prefix='section')
    if section_formset.is_valid():
        pub.save()
        for s in section_formset.ordered_forms:
            s.instance.order = s.cleaned_data['ORDER']
            s.save()

I've loked on S.O. but found nothing. Does anybody have a solution?

Thanks!!


Solution

  • Yes, you have the saving all jumbled up. Something like this:

    1 - Your formset holds the sets of SectionForm, so you are testing for the form to be valid in the wrong loop. You want this:

    if request.method == 'POST':
        section_formset = SectionFormSet(request.POST, instance=<an instance of Publication>, prefix='section')
        if section_formset.is_valid():
            instances = section_formset.save(commit=False)
            for instance in instances:
                 #do something
                 instance.save()
            return HttpResponseRedirect('<a url>')
    else:
        section_formset = SectionFormSet(instance=<an instance of Publication>, prefix='section')
    

    You don't need to do the instances loop if you're just saving the section forms 'order' value to the section models order attr - it's done for you. You can just call section_formset.save().