97 votes

Générer un fichier à télécharger avec Django

Est-il possible de créer une archive zip et de la proposer au téléchargement, sans toutefois enregistrer un fichier sur le disque dur?

113voto

muhuk Points 6526

Pour déclencher un téléchargement, vous devez définir l'en-tête Content-Disposition :

 from django.http import HttpResponse
from django.core.servers.basehttp import FileWrapper

# generate the file
response = HttpResponse(FileWrapper(myfile.getvalue()), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response
 

Si vous ne voulez pas le fichier sur le disque, vous devez utiliser StringIO

 import cStringIO as StringIO

myfile = StringIO.StringIO()
while not_finished:
    # generate chunk
    myfile.write(chunk)
 

Facultativement, vous pouvez également définir l'en-tête Content-Length :

 response['Content-Length'] = myfile.tell()
 

25voto

S.Lott Points 207588

Vous serez plus heureux de créer un fichier temporaire. Cela économise beaucoup de mémoire. Lorsque vous avez plus d'un ou deux utilisateurs simultanément, vous constaterez que la sauvegarde de la mémoire est très importante.

Vous pouvez cependant écrire sur un objet StringIO .

 >>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
 

L'objet "tampon" ressemble à un fichier avec une archive ZIP de 778 octets.

9voto

Soviut Points 26384

Oui, vous pouvez utiliser le zipfile module, zlib module ou d'autres modules de compression pour créer une archive zip dans la mémoire. Vous pouvez apporter votre point de vue écriture de l'archive zip à l' HttpResponse objet que le Django vue renvoie à la place de l'envoi d'un contexte à un modèle. Enfin, vous devez définir le type mime pour le format approprié pour indiquer au navigateur de traiter la réponse sous forme d'un fichier.

6voto

Ryan Anguiano Points 31

models.py

 from django.db import models

class PageHeader(models.Model):
    image = models.ImageField(upload_to='uploads')
 

views.py

 from django.http import HttpResponse
from StringIO import StringIO
from models import *
import os, mimetypes, urllib

def random_header_image(request):
    header = PageHeader.objects.order_by('?')[0]
    image = StringIO(file(header.image.path, "rb").read())
    mimetype = mimetypes.guess_type(os.path.basename(header.image.name))[0]

    return HttpResponse(image.read(), mimetype=mimetype)
 

5voto

dmitri Points 1184

Il y a un exemple de code sur http://djangosnippets.org/snippets/365/

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