alias51
alias51

Reputation: 8648

What's the correct syntax for multiple ValidationError functions?

I have a model on which I want to raise 2 conditional validation errors:

def clean(self):
    if self.personal_id_type == 0 and self.personal_id is None:
        raise ValidationError(
            {
                'personal_id_type': [
                    "ID type can not be 'None' if you have set a value.",
                ]
            }
        )

    if self.personal_phone_mobile is None and self.personal_phone_direct is None:
        raise ValidationError(
            {
                'personal_phone_mobile': [
                    'Please enter at least one personal phone number',
                ],
                'personal_phone_direct': [
                    'Please enter at least one personal phone number',
                ],
            }
        )

This displays the errors in isolation fine, so the logic is sound, however when both errors exist only the first exception is raised. Have I got the syntax wrong?

I want to be able to continue to use this in a Model (not a Form) display the error messages against the field_names.

Upvotes: 1

Views: 134

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477533

This is covered in the documentation in the raising multiple errors section [Django-doc].

If you detect multiple errors during a cleaning method and wish to signal all of them to the form submitter, it is possible to pass a list of errors to the ValidationError constructor.

They include an example:

# Good
raise ValidationError([
    ValidationError(_('Error 1'), code='error1'),
    ValidationError(_('Error 2'), code='error2'),
])

You thus can implement such validation with:

def clean(self):
    data = super().clean()
    errors = []
    if condition1:
        errors.append(ValidationError('Error1', code='error1')
    if condition2:
        errors.append(ValidationError('Error2', code='error2'))
    # ⋮
    if conditionn:
        errors.append(ValidationError('Errorn', code='errorn'))
    if errors:
        raise ValidationError(errors)
    return data

Note that for field-specific cleaning, you should implement a clean_fieldname method. See the cleaning a specific field attribute section for more information.

Upvotes: 1

Related Questions