Antworten:
Um einen Download auszulösen, müssen Sie den Content-DispositionHeader festlegen :
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
Wenn Sie die Datei nicht auf der Festplatte haben möchten, müssen Sie sie verwenden StringIO
import cStringIO as StringIO
myfile = StringIO.StringIO()
while not_finished:
# generate chunk
myfile.write(chunk)
Optional können Sie auch den Content-LengthHeader festlegen :
response['Content-Length'] = myfile.tell()
FileWrapperund es hat funktioniert.
Sie werden glücklicher sein, eine temporäre Datei zu erstellen. Das spart viel Speicher. Wenn Sie mehr als einen oder zwei Benutzer gleichzeitig haben, ist die Speichereinsparung sehr, sehr wichtig.
Sie können jedoch in ein StringIO- Objekt schreiben .
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
Das "Puffer" -Objekt ist dateiähnlich mit einem 778-Byte-ZIP-Archiv.
Warum nicht stattdessen eine TAR-Datei erstellen? Wie so:
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=anstelle vonmimetype=
Ja, Sie können das zipfile-Modul , das zlib-Modul oder andere Komprimierungsmodule verwenden , um ein zip-Archiv im Speicher zu erstellen. Sie können Ihre Ansicht veranlassen, das Zip-Archiv in das HttpResponseObjekt zu schreiben, das die Django-Ansicht zurückgibt, anstatt einen Kontext an eine Vorlage zu senden. Zuletzt müssen Sie den Mimetyp auf das entsprechende Format einstellen , damit der Browser die Antwort als Datei behandelt .
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)
Es gibt ein Codebeispiel unter 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
Sie können die Postleitzahl und den Inhaltstyp gemäß Ihren Anforderungen ersetzen.
fsock = open(filePath,"rb")
Gleiches gilt für das tgz-Archiv im Speicher:
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