Getting all validators assigned to a FileField

Use Case
I have a highly-reusable base form which I feed into a model form factory. Each model may have one or many FileFields. Each FileField will have different FileExtensionValidators. I would like to access the validators assigned to each FileField in order to extract the allowed_extensions so that I can use them to add {“accept”: “”} to the widget attrs for each file input on the form.

Note: This is just an attempt to improve the user experience. I’m not relying on this for security.

The Issue
I haven’t been able to figure out how to access the validators from any of the FileField objects. The validators are definitely working on the form, because files with invalid extensions raise validation errors as expected. But when I try to access the validators property from a FileField on an instantiated model, I get "AttributeError: ‘FieldFile’ has no attribute ‘validators’. And when I try to access the validators property from a FileField on the model class, I get "AttributeError: ‘FileDescriptor’ has no attribute ‘validators’.

The Question
Is there a way I can access the validator information for the validators assigned to a particular FileField? Or is there maybe a better way for me to try to achieve my goal?

Thanks in advance for any thoughts!

Hey there!
It would be useful to know how are you trying to access the validators.

Hi! Thanks for the question.

Since FileField inherits from Field, I had thought that the “validators” cached_property defined in Field would be accessible from a FileField as FileField.validators. But I get an AttributeError when I try that using my model class itself (model_class.file_field_name.validators) or an instance of the model (model_instance.file_field_name.validators). Maybe because FileField defines a different attr_class and descriptor_class?

Models are a strange beast…

The reference to “model_name.field_name” is not a reference to the field. It’s a property that provides a reference to the Python value stored in that field. (That’s why you can assign directly to the field name as “model_name.field_name = new_value”.)

If you want the instance of the field object itself, you can get it from the get_field method in the _meta object. e.g., model_name._meta.get_field('field_name') - or, since you want the list of validators, model_name._meta.get_field('field_name').validators

3 Likes

Thanks so much for the explanation and solution! That gives me exactly what I was looking for.