Opened 8 years ago

Last modified 8 years ago

#27263 closed New feature

Don't apply the rest of validators if the first one failed — at Version 4

Reported by: Alexey Rogachev Owned by: nobody
Component: Forms Version: dev
Severity: Normal Keywords: form, validator
Cc: Triage Stage: Someday/Maybe
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Alexey Rogachev)

I have a couple of validators for files, FileSizeValidator and FileTypeValidator.

I attach it to form field like this:

class ChartForm(forms.ModelForm):
    import_file = forms.FileField(required=False, label='File for import', validators = [
        FileSizeValidator(max_size='500 kb'),
        FileTypeValidator(extensions=('xlsx',))
    ])

Validators are extended from object and implement __init__ and __call__ methods (latter raises ValidationError).

The problem is, when I load the bigger file and with different extension, both validators execute and both error messages are shown for field (about exceeding max limit and wrong extension).

What I want - if first validator failed, don't even apply the rest of validators. For this specific scenario is not crucial, but in case of bigger amount of validators and more complex checks it can be a problem. For example if we need to read the file and verify that something exists there, why whe should do that if a size limit already exceeded.

Another option can be customizing each validator to not execute in case of existing errors.

I tried to add additional field argument to validator:

class FileSizeValidator(object):
    def __init__(self, max_size, field):
        self.max_size = max_size
        self.field = field

and pass it in form's __init __ method:

class ChartForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ChartForm, self).__init__(*args, **kwargs)        
        for validator in self.fields['import_file'].validators:
            validator.form = self.fields['import_file']

but I don't know how to properly call self.field.clean() which requires data. Besides that, this is not good approach, because some other validators (for example from Django core) can be attached to field.

Also this will require creating some additional mixin that must be attached along with validators.

I think there should be much simpler and elegant solution.

Can't find related questions or info in docs.

Change History (4)

comment:1 by Alexey Rogachev, 8 years ago

Description: modified (diff)

comment:2 by Alexey Rogachev, 8 years ago

Description: modified (diff)

comment:3 by Alexey Rogachev, 8 years ago

Description: modified (diff)

comment:4 by Alexey Rogachev, 8 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top