当我在Django中使用ajax上传文件时,我将按照本教程添加进度条。当我使用upload_to
选项将文件上传到文件夹时,一切都很好。但是当我使用storage
选项将文件上传到Azure时-它不起作用。例如,当这是我的模型时:
class UploadFile(models.Model):
title = models.CharField(max_length=50)
file=models.FileField(upload_to='files/media/pre')
它工作完美,但当这是我的模型:
from myAzure import AzureMediaStorage as AMS
class UploadFile(models.Model):
title = models.CharField(max_length=50)
file = models.FileField(storage=AMS)
它卡住了,没有进展。(AMS在myAzure.py中定义):
from storages.backends.azure_storage import AzureStorage
class AzureMediaStorage(AzureStorage):
account_name = '<myAccountName>'
account_key = '<myAccountKey>'
azure_container = 'media'
expiration_secs = None
我怎样才能使它工作?
编辑:如果不清楚:
- 我的问题不是上传到Azure,而是显示进度条。
- 出于安全原因,我不想从浏览器上传文件,而是从后端使用CORS和SAS。
当一个人将文件上传到一个特定的地方时,为了跟踪上传的当前状态,要么在Python对象周围添加一个包装器,要么在上传的地方提供一个回调来进行监控。
由于Azure库不提供该回调,因此可以为对象创建包装器或使用已有的包装器。
Alastair McCormack建议有一个名为tqdm的库,可以使用它的包装器。
正如George John所展示的,一个人可以做这样的事情
size = os.stat(fname).st_size
with tqdm.wrapattr(open(fname, 'rb'), "read", total=size) as data:
blob_client.upload_blob(data)
我可以建议尝试本地存储文件然后上传到Azure的解决方案。
不确定它是否会起作用,但至少你可以试一试,看看是否有帮助:
class UploadFile(models.Model):
title = models.CharField(max_length=50)
file = models.FileField(upload_to='files/media/pre', null=True, blank=False)
remote_file = models.FileField(storage=AMS, null=True, blank=True, default=None)
def save(self, *args, **kwargs):
if self.file:
self.remote_file = self.file
super().save(*args, **kwargs) # in theory - this should trigger upload of remote_file
self.file = None
super().save(*args, **kwargs)