Validate Uploaded File Size and Type in Django

JunePyo Suh·2020년 9월 12일
0

Because input file validation is a common step used widely throughout app APIs, it is more efficient to create a separate validator and reuse it.

Writing a validator

Requirements

pip install python-magic : pip install python-magic-bin==0.4.14 automatically fulfills libmagic dependency. However, it is highly likely to cause dependency issue with various AWS features. Hence, go with python-magic

brew install libmagic : This is required if you use python-magic, and an alternative (supposedly) pip install python-libmagic hasn't worked for me for some unidentified reason.

Code Snippet from Stackoverflow

In validators.py,

import magic

from django.utils.deconstruct import deconstructible
from django.template.defaultfilters import filesizeformat


@deconstructible
class FileValidator(object):
    error_messages = {
     'max_size': ("Ensure this file size is not greater than %(max_size)s."
                  " Your file size is %(size)s."),
     'min_size': ("Ensure this file size is not less than %(min_size)s. "
                  "Your file size is %(size)s."),
     'content_type': "Files of type %(content_type)s are not supported.",
    }

    def __init__(self, max_size=None, min_size=None, content_types=()):
        self.max_size = max_size
        self.min_size = min_size
        self.content_types = content_types

    def __call__(self, data):
        if self.max_size is not None and data.size > self.max_size:
            params = {
                'max_size': filesizeformat(self.max_size), 
                'size': filesizeformat(data.size),
            }
            raise ValidationError(self.error_messages['max_size'],
                                   'max_size', params)

        if self.min_size is not None and data.size < self.min_size:
            params = {
                'min_size': filesizeformat(self.min_size),
                'size': filesizeformat(data.size)
            }
            raise ValidationError(self.error_messages['min_size'], 
                                   'min_size', params)

        if self.content_types:
            content_type = magic.from_buffer(data.read(), mime=True)
            data.seek(0)

            if content_type not in self.content_types:
                params = { 'content_type': content_type }
                raise ValidationError(self.error_messages['content_type'],
                                   'content_type', params)

    def __eq__(self, other):
        return (
            isinstance(other, FileValidator) and
            self.max_size == other.max_size and
            self.min_size == other.min_size and
            self.content_types == other.content_types
        )

Usage in Serializers.py

validate_file = FileValidator(max_size=1024 * 100, 
                             content_types=('application/xml',))
file = models.FileField(upload_to=settings.XML_ROOT, 
                        validators=[validate_file])

2개의 댓글

comment-user-thumbnail
2021년 6월 14일

Good its

답글 달기
comment-user-thumbnail
2023년 4월 28일

Validating uploaded file size and type in Django is an important aspect of web application development. It helps to ensure that users are uploading files that meet the requirements of the application, such as file size and file type. Just you can check Virtual magician and get some new things about magic. This can be achieved using Django's built-in validators, which can be customized to meet specific requirements. By validating uploaded files, developers can help to prevent security issues and improve the overall user experience of their web application.

답글 달기