Opened 2 years ago
Closed 2 years 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 , 2 years ago
comment:2 by , 2 years 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.