Respuestas:
Para activar una descarga, debe configurar el Content-Disposition
encabezado:
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
Si no desea el archivo en el disco, debe usar StringIO
import cStringIO as StringIO
myfile = StringIO.StringIO()
while not_finished:
# generate chunk
myfile.write(chunk)
Opcionalmente, también puede configurar el Content-Length
encabezado:
response['Content-Length'] = myfile.tell()
FileWrapper
y funcionó.
Estarás más feliz creando un archivo temporal. Esto ahorra mucha memoria. Cuando tiene más de uno o dos usuarios al mismo tiempo, encontrará que el ahorro de memoria es muy, muy importante.
Sin embargo, puede escribir en un objeto StringIO .
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
El objeto "búfer" es similar a un archivo con un archivo ZIP de 778 bytes.
¿Por qué no crear un archivo tar en su lugar? Al igual que:
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=
lugar demimetype=
Sí, puede utilizar el módulo zipfile , el módulo zlib u otros módulos de compresión para crear un archivo zip en la memoria. Puede hacer que su vista escriba el archivo zip en el HttpResponse
objeto que devuelve la vista de Django en lugar de enviar un contexto a una plantilla. Por último, deberá configurar el tipo MIME en el formato adecuado para indicarle al navegador que trate la respuesta como un archivo .
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)
Hay un ejemplo de código en 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
Puede reemplazar el código postal y el tipo de contenido según sus requisitos.
fsock = open(filePath,"rb")
Lo mismo con el archivo tgz en 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