Câu trả lời:
Để kích hoạt tải xuống, bạn cần đặt Content-Disposition
tiêu đề:
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
Nếu bạn không muốn tệp trên đĩa, bạn cần sử dụng StringIO
import cStringIO as StringIO
myfile = StringIO.StringIO()
while not_finished:
# generate chunk
myfile.write(chunk)
Theo tùy chọn, bạn cũng có thể đặt Content-Length
tiêu đề:
response['Content-Length'] = myfile.tell()
FileWrapper
, và nó đã hoạt động.
Bạn sẽ hạnh phúc hơn khi tạo một tệp tạm thời. Điều này tiết kiệm rất nhiều bộ nhớ. Khi bạn có nhiều hơn một hoặc hai người dùng đồng thời, bạn sẽ thấy việc tiết kiệm bộ nhớ là rất rất quan trọng.
Tuy nhiên, bạn có thể ghi vào một đối tượng StringIO .
>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
Đối tượng "bộ đệm" có dạng tệp với tệp nén ZIP 778 byte.
Tại sao không tạo một tệp tar thay vào đó? Như vậy:
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=
thay vìmimetype=
Có, bạn có thể sử dụng mô-đun zipfile , mô-đun zlib hoặc các mô-đun nén khác để tạo tệp nén zip trong bộ nhớ. Bạn có thể làm cho chế độ xem của mình ghi lưu trữ zip vào HttpResponse
đối tượng mà chế độ xem Django trả về thay vì gửi ngữ cảnh đến một mẫu. Cuối cùng, bạn sẽ cần đặt mimetype thành định dạng thích hợp để yêu cầu trình duyệt coi phản hồi như một tệp .
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ó một ví dụ về mã tại 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
Bạn có thể thay thế loại zip và nội dung theo yêu cầu của bạn.
fsock = open(filePath,"rb")
Tương tự với trong kho lưu trữ tgz bộ nhớ:
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