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?
Réponses
Trop de publicités? 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()
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.
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.
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)
Il y a un exemple de code sur http://djangosnippets.org/snippets/365/