Thanks Ned, I had misunderstood the concept of "file-like" and you've
explained it admirably, exactly what I needed to know. Though
Malcolm's tip regarding the unsuitability of HttpResponse as a
flotation device will be a life-saver for many, I'm sure.
This is what works for me:
import cStringIO, zipfile
response = HttpResponse(mimetype='application/zip')
response['Content-Disposition'] = 'attachment; filename=zipfile.zip'
fobj = cStringIO.StringIO()
f = zipfile.ZipFile(fobj, "w")
f.write(filename)
f.close()
zip = fobj.getvalue()
fobj.close()
response.write(zip)
return response
On Feb 21, 12:34 pm, Ned Batchelder <
n...@nedbatchelder.com> wrote:
> In Python, there is a loose concept of a "file-like" object. This means
> that the object behaves like a file under duck-typing, meaning it has
> the right methods to be treated just as if it were a file. But the
> concept is only loosely defined, and different file-like objects
> implement different numbers of methods, according to their abilities.
> HttpResponse does not implement seek(), and many consumers of file-like
> objects don't ever call seek(), so HttpResponses can be used as files in
> many cases. ZipFile seems to be one case where it cannot, because
> ZipFile calls seek().
>
> Both the HttpRequest docs
> (
http://www.djangoproject.com/documentation/request_response/) and the
> Python file docs (
http://docs.python.org/lib/bltin-file-objects.html)
> mention "file-like" obliquely, with reference to methods that are or are
> not, or may or may not, be implemented.
>
> As Malcolm points out, seek() would require buffering, which you can
> provide by using an intermediary like StringIO.
>
> --Ned.
http://nedbatchelder.com/blog