13👍
HttpResponse takes a string or an iterator returning strings (like an open file-like object). You are passing it the file path, so the response contains a file whose content is just the file path instead of the valid zip content you wrote to the file. You can just use open
as the HTTPResponse
object will close the file for you:
response = HttpResponse(open(file_path, 'rb'), content_type='application/zip')
Quoting the docs:
Finally, you can pass HttpResponse an iterator rather than strings. HttpResponse will consume the iterator immediately, store its content as a string, and discard it. Objects with a close() method such as files and generators are immediately closed.
If you need the response to be streamed from the iterator to the client, you must use the StreamingHttpResponse class instead.
Writing to disk on every request may hurt your server I/O – looking at your code, everything seems small enough to fit memory. You can use (C)StringIO (BytesIO in Python3) instead of real files:
from io import BytesIO
mem_file = BytesIO()
with zipfile.ZipFile(mem_file, "w") as zip_file:
for i, planner in enumerate(planner_list):
file_name = str(planner[0].start_date)
content = render_to_string('deneme.html', {'schedule':schedule})
zip_file.writestr(file_name, content)
f.seek(0) # rewind file pointer just in case
response = HttpResponse(f, content_type='application/zip')