9

If the user fills a form in formset incompletely and then marks it for deletion, my form handling dies horribly. The deleted forms prevent formset.cleaned_data from working as they don't validate and thus the form doesn't have a cleaned_data attribute. If I try to iterate over formset.deleted_forms and delete the forms from formset.forms, then formset.cleaned_data crashes due to index out of range.

How should I be handling these invalid forms the user didn't want anyway?

( This is my error, I have copied description from google groups)

I don't understant the error because looking into django code I can read this:

def is_valid(self):
    """
    Returns True if form.errors is empty for every form in self.forms.
    """
    if not self.is_bound:
        return False
    # We loop over every form.errors here rather than short circuiting on the
    # first failure to make sure validation gets triggered for every form.
    forms_valid = True
    err = self.errors
    for i in range(0, self.total_form_count()):
        form = self.forms[i]
        if self.can_delete:                           <-------
            if self._should_delete_form(form):
                # This form is going to be deleted so any of its errors
                # should not cause the entire formset to be invalid.
                continue
        if bool(self.errors[i]):
            forms_valid = False
    return forms_valid and not bool(self.non_form_errors())

At this time, this is my code to avoid errors:

formFac = modelformset_factory(prm_model, extra = extra, can_delete = prm_can_delete )

if request.method == 'POST':
    formSet = formFac( request.POST )
    hi_ha_errors = False
    if formSet.is_valid():
        for form in formSet:
            if form not in formSet.deleted_forms:
                form.save()
        for form in formSet.deleted_forms:
            instance = form.instance
            if instance.pk:
                try:
                    instance.delete()
                except Exception, e:                    
                    form._errors.setdefault(NON_FIELD_ERRORS, []).append( 
                          'This row is referenced by others.'  )
                    hi_ha_errors = True

        if not hi_ha_errors:
            return HttpResponseRedirect( prm_url_next )     
9
  • Same problem here.. debugging! Commented Oct 9, 2012 at 16:17
  • @TomaszZielinski, Solved yet for me. Problem was with dynamic forms. Let me know if you need some help. Commented Oct 9, 2012 at 21:30
  • Solved here as well. But those formsets are "1990-sh" :) Commented Oct 12, 2012 at 19:26
  • 1
    post your answer, i will check as solution Commented Oct 12, 2012 at 19:37
  • anyone interested in posting the answer here? Commented Jan 30, 2014 at 17:08

1 Answer 1

0

The way I solved this is to override the full_clean() method of my Form/ModelForm used in the Formset/ModelFormset

class MyModelForm(ModelForm):

    def full_clean(self, *args, **kwargs):
        super(MyModelForm, self).full_clean(*args, **kwargs)
        if hasattr(self, 'cleaned_data') and self.cleaned_data.get('DELETE', False):
            self._errors = ErrorDict()

If the form delete box is checked, this clears the error list.. the form will be displayed with no errors. But if the user unchecks the delete box and resubmits, then the form will show errors as normal.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.