Risposte:
Per attivare un download è necessario impostare l' Content-Dispositionintestazione:
from django.http import HttpResponse
from wsgiref.util import FileWrapper
# generate the file
response = HttpResponse(FileWrapper(myfile.getvalue()), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response
Se non vuoi il file su disco devi usare StringIO
import cStringIO as StringIO
myfile = StringIO.StringIO()
while not_finished:
# generate chunk
myfile.write(chunk)
Facoltativamente puoi impostare anche l' Content-Lengthintestazione:
response['Content-Length'] = myfile.tell()
FileWrapper, e ha funzionato.
Sarai più felice di creare un file temporaneo. Ciò consente di risparmiare molta memoria. Quando hai più di uno o due utenti contemporaneamente, scoprirai che il risparmio di memoria è molto, molto importante.
È tuttavia possibile scrivere su un oggetto StringIO .
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
L'oggetto "buffer" è simile a un file con un archivio ZIP da 778 byte.
Perché invece non creare un file tar? Così:
def downloadLogs(req, dir):
response = HttpResponse(content_type='application/x-gzip')
response['Content-Disposition'] = 'attachment; filename=download.tar.gz'
tarred = tarfile.open(fileobj=response, mode='w:gz')
tarred.add(dir)
tarred.close()
return response
content_type=posto dimimetype=
Sì, puoi utilizzare il modulo zipfile , il modulo zlib o altri moduli di compressione per creare un archivio zip in memoria. Puoi fare in modo che la tua vista scriva l'archivio zip HttpResponsesull'oggetto restituito dalla vista Django invece di inviare un contesto a un modello. Infine, dovrai impostare il tipo MIME sul formato appropriato per dire al browser di trattare la risposta come un file .
from django.db import models
class PageHeader(models.Model):
image = models.ImageField(upload_to='uploads')
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)
C'è un esempio di codice su http://djangosnippets.org/snippets/365/
def download_zip(request,file_name):
filePath = '<path>/'+file_name
fsock = open(file_name_with_path,"rb")
response = HttpResponse(fsock, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response
È possibile sostituire zip e tipo di contenuto secondo le proprie esigenze.
fsock = open(filePath,"rb")
Lo stesso con l'archivio tgz in memoria:
import tarfile
from io import BytesIO
def serve_file(request):
out = BytesIO()
tar = tarfile.open(mode = "w:gz", fileobj = out)
data = 'lala'.encode('utf-8')
file = BytesIO(data)
info = tarfile.TarInfo(name="1.txt")
info.size = len(data)
tar.addfile(tarinfo=info, fileobj=file)
tar.close()
response = HttpResponse(out.getvalue(), content_type='application/tgz')
response['Content-Disposition'] = 'attachment; filename=myfile.tgz'
return response