Django - 如何上传文件到云端(Azure Blob 存储),并显示上传进度条

3
我在使用ajax上传文件到Django时,按照这篇教程添加进度条。使用 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,而是从我的后端上传文件。

这个回答解决了你的问题吗?Django Azure上传文件到Blob存储 - Ecstasy
将文件从浏览器上传到Azure Blob存储并显示上传进度 - Ecstasy
@DeepDave-MT 不是的。我的问题不是上传,而是在上传时显示进度条。我编辑了问题以使其更清晰。 - Binyamin Even
2个回答

1
当某人将文件上传到特定位置时,为了跟踪上传的当前状态,可以在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)

谢谢您的回答!我也看到了这个,但是我不知道如何在视图中创建UploadFile实例时集成它(并将进度显示在模板中以供客户端查看)? - Binyamin Even
你是从哪里获取 from storages.backends.azure_storage import AzureStorage 的?看起来你正在尝试使用自定义存储类,但是使用了django-storages [azure]。是这样吗? - Gonçalo Peres
另外,你定义了AZURE_LOCATION吗?这个问题之前也出现过 - Gonçalo Peres
@BinyaminEven 只是提醒一下我的先前评论。 - Gonçalo Peres

0

我建议尝试一下将文件存储在本地,然后再上传到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)
        

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接