Bir zip arşivi oluşturup indirmeyi teklif etmek mümkün, ancak yine de bir dosyayı sabit sürücüye kaydetmiyor mu?
Yanıtlar:
Bir indirmeyi tetiklemek için Content-Disposition
başlığı ayarlamanız gerekir :
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
Dosyayı diskte istemiyorsanız kullanmanız gerekir StringIO
import cStringIO as StringIO
myfile = StringIO.StringIO()
while not_finished:
# generate chunk
myfile.write(chunk)
İsteğe bağlı Content-Length
olarak başlığı da ayarlayabilirsiniz :
response['Content-Length'] = myfile.tell()
FileWrapper
ve işe yaradı.
Geçici bir dosya oluşturmaktan daha mutlu olacaksınız. Bu, çok fazla bellek tasarrufu sağlar. Aynı anda birden fazla veya iki kullanıcınız olduğunda, bellek tasarrufunun çok, çok önemli olduğunu göreceksiniz.
Bununla birlikte, bir StringIO nesnesine yazabilirsiniz .
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
"Tampon" nesnesi, 778 baytlık bir ZIP arşiviyle dosya gibidir.
Neden bunun yerine bir tar dosyası yapmıyorsunuz? Şöyle:
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=
yerine sahip olmalısınızmimetype=
Evet, bellekte bir zip arşivi oluşturmak için zipfile modülünü , zlib modülünü veya diğer sıkıştırma modüllerini kullanabilirsiniz. Görünümünüzün HttpResponse
, bir şablona bağlam göndermek yerine, Django görünümünün döndürdüğü nesneye zip arşivini yazmasını sağlayabilirsiniz . Son olarak, tarayıcıya yanıtı bir dosya olarak değerlendirmesini söylemek için mime tipini uygun biçime ayarlamanız gerekir .
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)
Http://djangosnippets.org/snippets/365/ adresinde bir kod örneği var.
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
Zip ve içerik türünü ihtiyacınıza göre değiştirebilirsiniz.
fsock = open(filePath,"rb")
Bellek tgz arşiviyle aynı:
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