Reputation: 169
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
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/
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