classes representing uploaded files an abstract uploaded file temporaryuploadedfile and inmemoryuploadedfile are the builtin concrete subclasses an uploadedfile object behaves somewhat like a file object and represents some file data that the user submitted with a form sanitize the file name so that it can t be dangerous just use the basename of the file anything else is dangerous file names longer than 255 characters can cause problems on older oses a file uploaded to a temporary location i e streamtodisk return the full path of this file return self file name def closeself try return self file close except filenotfounderror the file was moved or deleted before the tempfile could unlink it still sets self file closecalled and calls self file file close before the exception pass class inmemoryuploadedfileuploadedfile def init self file fieldname name contenttype size charset contenttypeextranone super initfile name contenttype size charset contenttypeextra self fieldname fieldname def openself modenone self file seek0 return self def chunksself chunksizenone self file seek0 yield self read def multiplechunksself chunksizenone since it s in memory we ll never have multiple chunks return false class simpleuploadedfileinmemoryuploadedfile def initself name content contenttypetextplain content content or b super init bytesiocontent none name contenttype lencontent none none classmethod def fromdictcls filedict return cls filedictfilename filedictcontent filedict getcontenttype textplain an abstract uploaded file temporaryuploadedfile and inmemoryuploadedfile are the built in concrete subclasses an uploadedfile object behaves somewhat like a file object and represents some file data that the user submitted with a form sanitize the file name so that it can t be dangerous just use the basename of the file anything else is dangerous file names longer than 255 characters can cause problems on older oses a file uploaded to a temporary location i e stream to disk return the full path of this file the file was moved or deleted before the tempfile could unlink it still sets self file close_called and calls self file file close before the exception a file uploaded into memory i e stream to memory since it s in memory we ll never have multiple chunks a simple representation of a file which just has content size and a name create a simpleuploadedfile object from a dictionary with keys filename content type content
import os
from io import BytesIO

from django.conf import settings
from django.core.files import temp as tempfile
from django.core.files.base import File
from django.core.files.utils import validate_file_name

__all__ = (
    "UploadedFile",
    "TemporaryUploadedFile",
    "InMemoryUploadedFile",
    "SimpleUploadedFile",
)


class UploadedFile(File):
    

    def __init__(
        self,
        file=None,
        name=None,
        content_type=None,
        size=None,
        charset=None,
        content_type_extra=None,
    ):
        super().__init__(file, name)
        self.size = size
        self.content_type = content_type
        self.charset = charset
        self.content_type_extra = content_type_extra

    def __repr__(self):
        return "<%s: %s (%s)>" % (self.__class__.__name__, self.name, self.content_type)

    def _get_name(self):
        return self._name

    def _set_name(self, name):
        
        if name is not None:
            
            name = os.path.basename(name)

            
            if len(name) > 255:
                name, ext = os.path.splitext(name)
                ext = ext[:255]
                name = name[: 255 - len(ext)] + ext

            name = validate_file_name(name)

        self._name = name

    name = property(_get_name, _set_name)


class TemporaryUploadedFile(UploadedFile):
    

    def __init__(self, name, content_type, size, charset, content_type_extra=None):
        _, ext = os.path.splitext(name)
        file = tempfile.NamedTemporaryFile(
            suffix=".upload" + ext, dir=settings.FILE_UPLOAD_TEMP_DIR
        )
        super().__init__(file, name, content_type, size, charset, content_type_extra)

    def temporary_file_path(self):
        
        return self.file.name

    def close(self):
        try:
            return self.file.close()
        except FileNotFoundError:
            
            
            
            pass


class InMemoryUploadedFile(UploadedFile):
    

    def __init__(
        self,
        file,
        field_name,
        name,
        content_type,
        size,
        charset,
        content_type_extra=None,
    ):
        super().__init__(file, name, content_type, size, charset, content_type_extra)
        self.field_name = field_name

    def open(self, mode=None):
        self.file.seek(0)
        return self

    def chunks(self, chunk_size=None):
        self.file.seek(0)
        yield self.read()

    def multiple_chunks(self, chunk_size=None):
        
        return False


class SimpleUploadedFile(InMemoryUploadedFile):
    

    def __init__(self, name, content, content_type="text/plain"):
        content = content or b""
        super().__init__(
            BytesIO(content), None, name, content_type, len(content), None, None
        )

    @classmethod
    def from_dict(cls, file_dict):
        
        return cls(
            file_dict["filename"],
            file_dict["content"],
            file_dict.get("content-type", "text/plain"),
        )