python - django打开的文件类型到python打开的文件类型
问题描述
我有一个要求用户上传图像的 django 应用程序。我从 html django 获取图像。我将此图像作为参数传递给 python 脚本。我对这张图片做了很多事情(比如使用 PIL 库),参数的类是:
'django.core.files.uploadedfile.InMemoryUploadedFile'
但是当我尝试使用一个要求预先确定的python .open() 类型的函数时,问题就来了,即:
'_io.BufferedReader'
具体来说,我正在使用的功能是:
block_blob_service.create_blob_from_stream()
(Microsoft Azure 功能)
所以我的问题是,我可以从 django 打开的文件类型转换为 python 打开的文件类型吗?可能没有保存文件并再次打开。
而且,如果有任何机会,有人使用过这个库,我也尝试过block_blob_service.create_blob_from_bytes()
但它不起作用(从 django 转换为我刚刚完成img = django_input.read()
的字节(我得到一个 Bytes 类型)并且block_blob_service.create_blob_from_path()
, 不是一个选项,因为我无法获取文件的路径,也不想保存图像并获取新路径。
解决方案
仅根据 的源代码django.core.files.uploadedfile
,类InMemoryUploadedFile
继承自继承自的类UploadedFile
,django.core.files.base.File
如下代码和图所示。
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
下图来自https://docs.djangoproject.com/en/2.2/ref/files/uploads/
因此,您可以从InMemoryUploadedFile
object 获取数据字节并将其传递给 function block_blob_service.create_blob_from_bytes
。
同时,正如我所知,这不是一个好主意。在 Django 中从上传的文件创建 blob 的简单解决方案是django-storages
与 Azure Storage 后端一起使用,请参阅其有关Azure Storage的文档以了解如何使用。还有现有的类似 SO thread Django Azure upload file to blob storage,你可以参考一下。
推荐阅读
- sql - node-postgres:我无法弄清楚我的查询有什么问题?(错误:“a”处或附近的语法错误)
- hive - Hive 外部表返回零行
- firefox - Ubuntu 上的 Firfeox 87 为 RTCRtp[Sender|Receiver].getCapabilities 抛出 TypeError
- javascript - 了解 Firebase 身份验证流程中的 onSignIn 函数 - 为什么声明取消订阅并立即调用?
- gerrit - 是否有任何 gerrit 查询来确定在特定 gerrit 项目中对其他分支进行了多少更改?
- c# - 无法让 Polly 使用折叠请求
- r - 如何在同一管道中改变给定特定日期格式的日期?
- database - 对于只接受少数值的列,应该在 Google 大查询中使用什么数据类型?
- java - 为什么在 Tomcat 8.5 上调用 Java findClass() 可能需要 7 分钟?
- java - 如何在 AndroidKeyStore 中存储对称密钥?