Opened 16 months ago
Closed 16 months ago
#34700 closed New feature (duplicate)
ValidatedFileField
Reported by: | Reza Shakeri | Owned by: | nobody |
---|---|---|---|
Component: | File uploads/storage | Version: | 4.2 |
Severity: | Normal | Keywords: | file, file validator, file validation, validator, file |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi
I want to add a valid file field (ValidatedFileField) to Django that checks the size, MIME and extension of files as well as their validity using the Python (mimetypes : https://docs.python.org/3/library/mimetypes.html) Built-in Library And the same is tested, ValidatedFileField makes files more reliable
class ValidatedFileField(FileField): """ :return: If everything is OK, it will return None, otherwise it will return a ValidationError. """ def __init__(self, *args, **kwargs): """ :type acceptable_mimes: list :param acceptable_mimes: The mimes you want the file to be checked based on, example: image/png :type max_upload_file_size: int, optional :param max_upload_file_size: If you want the file size to be checked, the file size must be in bytes, example: file_size=1048576 (1MB), defaults to 0, optional :raises ValueError: If the mime list is empty, raised a value error :raises ValueError: If the library you entered is not supported, raised a value error, Supported library: filetype, mimetypes, pure_magic, python_magic :raises ValidationError: if file not valid """ self.max_upload_file_size: int = kwargs.pop("max_upload_file_size", None) self.acceptable_mimes: list = kwargs.pop("acceptable_mimes", None) self.acceptable_extensions: list = kwargs.pop("acceptable_extensions", None) if acceptable_mimes is None: raise ValueError("acceptable mimes are empty") if acceptable_mimes is not None: if len(acceptable_mimes) == 1: return False group = groupby(acceptable_mimes) mimes_is_equal = next(group, True) and not next(group, False) if mimes_is_equal: raise ValueError("acceptable mimes are equal") super().__init__(*args, **kwargs) def deconstruct(self): name, path, args, kwargs = super().deconstruct() kwargs["acceptable_mimes"] = self.acceptable_mimes kwargs["acceptable_extensions"] = self.acceptable_extensions kwargs["max_upload_file_size"] = self.max_upload_file_size return name, path, args, kwargs def clean(self, *args, **kwargs): data = super().clean(*args, **kwargs) current_file = data.file file_size = data.size file_path = TemporaryUploadedFile.temporary_file_path(current_file) if self.acceptable_mimes is not None: try: content_type = current_file.content_type except AttributeError: content_type = None file_mime = guess_type(file_path)[0] if content_type is not None and content_type not in self.acceptable_mimes: raise ValidationError("file mime is not valid") if file_mime is not None and file_mime not in self.acceptable_mimes: raise ValidationError("file mime is not valid") if self.acceptable_extensions is not None: file_extension = Path(file_path).suffix if file_extension not in self.acceptable_extensions: raise ValidationError("file extentions is not valid") if self.max_upload_file_size is not None: file_size = os.path.getsize(file_path) if ( self.max_upload_file_size is not None and file_size > self.max_upload_file_size ): raise ValidationError("file size is not valid")
Change History (2)
comment:1 by , 16 months ago
comment:2 by , 16 months ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Note:
See TracTickets
for help on using tickets.
The proposed feature looks promising. However, it seems like the file field has too much responsibility which I am not sure if it would best practice for a django file field. Different validation classes could be used for each one of the validations.
In addition, I don't know why the use of file type checking library should be an option for the developer to use as long as they could all give you the desired output.