3 votes

Django - télécharger un fichier dans le cloud (stockage blob Azure) avec une barre de progression

Je suis en train de suivre ce tutoriel pour ajouter une barre de progression lorsque je télécharge un fichier dans Django, en utilisant ajax. Lorsque je télécharge le fichier dans un dossier en utilisant l'option upload_to, tout fonctionne bien. Mais lorsque je télécharge le fichier sur Azure en utilisant l'option storage - cela ne fonctionne pas. c'est-à-dire quand c'est mon modèle:

class UploadFile(models.Model):
    title = models.CharField(max_length=50)
    file=models.FileField(upload_to='files/media/pre')

Cela fonctionne parfaitement, mais lorsque c'est mon modèle:

from myAzure import AzureMediaStorage as AMS
class UploadFile(models.Model):
    title = models.CharField(max_length=50)
    file = models.FileField(storage=AMS)

Il reste bloqué et ne progresse pas. (AMS est défini dans myAzure.py par):

from storages.backends.azure_storage import AzureStorage

class AzureMediaStorage(AzureStorage):
    account_name = ''
    account_key = ''
    azure_container = 'media'
    expiration_secs = None

Comment puis-je faire fonctionner cela?

EDIT: Si ce n'était pas clair:

  • mon problème n'est pas de télécharger sur Azure, mais d'afficher la barre de progression.
  • Pour des raisons de sécurité, je ne veux pas télécharger le fichier depuis le navigateur et utiliser CORS et SAS mais depuis mon backend.

1voto

Goncalo Peres Points 1695

Lorsque l'on télécharge un fichier à un endroit spécifique, afin de suivre l'état actuel du téléchargement, on ajoute soit un wrapper autour de l'objet Python soit l'endroit où l'on télécharge fournit un callback pour le suivi.

Comme la bibliothèque Azure ne fournit pas ce callback, on peut créer un wrapper pour l'objet ou en utiliser un déjà existant.

Il y a une bibliothèque suggérée par Alastair McCormack nommée tqdm avec un tel wrapper que l'on peut utiliser.

Comme le montre George John, on peut faire quelque chose comme ceci

size = os.stat(fname).st_size
with tqdm.wrapattr(open(fname, 'rb'), "read", total=size) as data:
    blob_client.upload_blob(data)

0voto

Egor Wexler Points 538

Je peux suggérer d'essayer la solution de contournement de stocker le fichier localement et ensuite de l'envoyer vers Azure.

Je ne suis pas sûr que cela fonctionnera mais au moins vous pouvez essayer et nous dire si cela aide :

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)  # en théorie - cela devrait déclencher l'envoi de remote_file
            self.file = None 
        super().save(*args, **kwargs)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X