polaupa
polaupa

Reputation: 169

django opened file type to python opened file type

I have a django app that asks the user to upload an image. I get the image from html django. This image I pass to the python script as a parameter. I did a lot of stuff with this image (like using the PIL libraries), the class of the parameter is:

'django.core.files.uploadedfile.InMemoryUploadedFile'

But the problem comes when I try to use one function that ask for the predeterminate type of .open() of python, that is:

'_io.BufferedReader'

Concretely, the function I'm using is: block_blob_service.create_blob_from_stream() (a Microsoft Azure function)

So my question is, can I convert from django opened file type to python opened file type? It may be without saving the file and opening again.

And, if by any chance, somebody has worked with this library, I've also tried block_blob_service.create_blob_from_bytes() and it's not working (to convert from django to bytes I've just done img = django_input.read() (I get a Bytes type) and block_blob_service.create_blob_from_path(), is not an option, because I can't get the path of the file, nor I don't want to save the image and get a new path.

Upvotes: 1

Views: 1327

Answers (1)

Peter Pan
Peter Pan

Reputation: 24138

Just according to the source code for django.core.files.uploadedfile, class InMemoryUploadedFile inherit from class UploadedFile which inherit from django.core.files.base.File, as the code and figure below said.

from django.core.files.base import File

class UploadedFile(File):
    """
    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.
    """

    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):
        # Sanitize the file name so that it can't be dangerous.
        if name is not None:
            # Just use the basename of the file -- anything else is dangerous.
            name = os.path.basename(name)

            # File names longer than 255 characters can cause problems on older OSes.
            if len(name) > 255:
                name, ext = os.path.splitext(name)
                ext = ext[:255]
                name = name[:255 - len(ext)] + ext

        self._name = name

    name = property(_get_name, _set_name)

class InMemoryUploadedFile(UploadedFile):
    """
    A file uploaded into memory (i.e. stream-to-memory).
    """
    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):
        # Since it's in memory, we'll never have multiple chunks.
        return False

The figure below comes from https://docs.djangoproject.com/en/2.2/ref/files/uploads/ enter image description here

So you can get the data bytes from InMemoryUploadedFile object and pass it to the function block_blob_service.create_blob_from_bytes.

Meanwhile, as I known, it's not a good idea. The simple solution for creating a blob from the uploaded file in Django is to use django-storages with Azure Storage backend, please see its document about Azure Storage to know how to use. And there is the existing similar SO thread Django Azure upload file to blob storage which you can refer to.

Upvotes: 1

Related Questions