I have the following code for managing file download through django.
def serve_file(request, id): file = models.X.objects.get(id=id).file #FileField file.open('rb') wrapper = FileWrapper(file) mt = mimetypes.guess_type(file.name)[0] response = HttpResponse(wrapper, content_type=mt) import unicodedata, os.path filename = unicodedata.normalize('NFKD', os.path.basename(file.name)).encode("utf8",'ignore') filename = filename.replace(' ', '-') #Avoid browser to ignore any char after the space response['Content-Length'] = file.size response['Content-Disposition'] = 'attachment; filename={0}'.format(filename) #print response return responseUnfortunately, my browser get an empty file when downloading.
The printed response seems correct:
Content-Length: 3906 Content-Type: text/plain Content-Disposition: attachment; filename=toto.txt blah blah ....I have similar code running ok. I don't see what can be the problem. Any idea?
PS: I have tested the solution proposed here and get the same behavior
Update: Replacing wrapper = FileWrapper(file) by wrapper = file.read() seems to fix the problem
Update: If I comment the print response , I get similar issue:. the file is empty. Only difference: FF detects a 20bytes size. (the file is bigger than this)
File object is an interable, and a generator. It can be read only once before being exausted. Then you have to make a new one, of use a method to start at the begining of the object again (e.g: seek() ).
read() returns a string, which can be read multiple times without any problem, this is why it solves your issue.
So just make sure that if you use a file like object, you don't read it twice in a row. E.G: don't print it, then returns it.