InlineFormSet validation

53 views
Skip to first unread message

César García Tapia

unread,
Jun 1, 2014, 11:52:56 AM6/1/14
to django...@googlegroups.com
Hi. I already asked this question in StackOverflow, but I didn't get any useful answer. Let's try here :-)

I have a BaseInlineFormSet, and I'd like to validate a field in the parent form based on the values on the fields of the children. As seen in the docs, the only method to make a custom validation is clean(), but I can't find a way to add errors to the parent form, only for the children.

In the following code I build a formula. Each variable comes from a inner form, and if the global formula don't validate, I'd like to add an error to the parent's form field formula

class CustomInlineFormSet(BaseInlineFormSet):
    def clean(self):
        formula = self.instance.formula
        variables = []
        for form in self.forms:
            if 'formula_variable' in form.cleaned_data:
                variables.append(form.cleaned_data['formula_variable'])

        valid, msg = validate_formula(formula, variables)
        if not valid:
            WHAT HERE???

Thank you!!

Russell Keith-Magee

unread,
Jun 1, 2014, 8:26:56 PM6/1/14
to Django Users
Hi Cesar,

It's all the documentation:


You just have to raise a ValidationError(); Django will then add an error that spans the entire formset. 

If you want to evaluate errors in clean(), but force the actual error to appear against a specific field, that's possible too - you just need to emulate what Django is doing behind the scenes. That means inserting the error into the error dictionary, and removing the error value from cleaned_data:

    self._errors['field name'] = self.error_class(['This field has a problems'])
    del cleaned_data['field_name']

You might need to do this if you won't know if a specific value is valid until you've checked all the individual values (e.g., A must be greater than B - you can't check that until you know both A and B exist, which won't be the case in the clean_A and clean_B methods)

I hope that helps!

Yours,
Russ Magee %-)



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/87ce32a8-782e-4248-8b8c-046b6eef0904%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

César García Tapia

unread,
Jun 2, 2014, 3:47:17 AM6/2/14
to django...@googlegroups.com
Hi, Russell, thanks for answering :-)

Your answer helps me, but not completely. I can add the error with this:

    self._errors.append({'formula': self.error_class([msg])})  # self._errors in a BaseInlineFormSet is a list of dictionaries, not a dictionary, like you say.

But I don't know how to reach the cleaned_data of the parent form. If I do this:

    del self.cleaned_data['formula']

It says that the parent form doesn't have a 'cleaned_data' attribute.

So I can make the InlineFormSet validation fail, but I can't show the error in my template.

Any suggestion?

Thank you!!

César García Tapia

unread,
Jun 3, 2014, 6:14:56 AM6/3/14
to django...@googlegroups.com
Ok, thanks to Russell's help in IRC I managed to solve this. Thank you so much!!
Reply all
Reply to author
Forward
0 new messages