[Django] #34700: ValidatedFileField

10 views
Skip to first unread message

Django

unread,
Jul 7, 2023, 7:31:37 PM7/7/23
to django-...@googlegroups.com
#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.

Django

unread,
Jul 8, 2023, 10:36:07 AM7/8/23
to django-...@googlegroups.com
#34700: ValidatedFileField
-------------------------------------+-------------------------------------
Reporter: Reza Shakeri | Owner: nobody
Type: New feature | Status: new

Component: File | Version: 4.2
uploads/storage |
Severity: Normal | Resolution:
Keywords: file, file | Triage Stage:
validator, file validation, | Unreviewed
validator, file |

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Abdulla Dlshad):

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/34700#comment:1>

Django

unread,
Jul 8, 2023, 1:20:45 PM7/8/23
to django-...@googlegroups.com
#34700: ValidatedFileField
-------------------------------------+-------------------------------------
Reporter: Reza Shakeri | Owner: nobody
Type: New feature | Status: closed

Component: File | Version: 4.2
uploads/storage |
Severity: Normal | Resolution: duplicate

Keywords: file, file | Triage Stage:
validator, file validation, | Unreviewed
validator, file |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => duplicate


Comment:

Another duplicate of #33942 and #34263.

--
Ticket URL: <https://code.djangoproject.com/ticket/34700#comment:2>

Reply all
Reply to author
Forward
0 new messages