#34700: ValidatedFileField
-------------------------------------+-------------------------------------
Reporter: Reza | Owner: nobody
Shakeri |
Type: New | Status: new
feature |
Component: File | Version: 4.2
uploads/storage | Keywords: file, file
Severity: Normal | validator, file validation,
Triage Stage: | validator, file
Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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")
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34700>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018932b24cce-f7c067e4-4ee2-42ac-9f70-bafbd50cf63c-000000%40eu-central-1.amazonses.com.