Django возвращает файл через HttpResponse - файл не подается правильно
Я хочу вернуть некоторые файлы в HttpResponse, и я использую следующую функцию. Файл, который возвращается, всегда имеет размер файла 1 КБ, и я не знаю, почему. Я могу открыть файл, но кажется, что он не работает правильно. Таким образом, я хотел знать, как можно возвращать файлы с django/python через HttpResponse.
@login_required
def serve_upload_files(request, file_url):
import os.path
import mimetypes
mimetypes.init()
try:
file_path = settings.UPLOAD_LOCATION + '/' + file_url
fsock = open(file_path,"r")
#file = fsock.read()
#fsock = open(file_path,"r").read()
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
print "file size is: " + str(file_size)
mime_type_guess = mimetypes.guess_type(file_name)
if mime_type_guess is not None:
response = HttpResponse(fsock, mimetype=mime_type_guess[0])
response['Content-Disposition'] = 'attachment; filename=' + file_name
except IOError:
response = HttpResponseNotFound()
return response
Изменить:
Ошибка на самом деле не является ошибкой; -)
Это решение работает на сервере Apache, поэтому источник в порядке.
При написании этого вопроса я тестировал его локально с сервером разработки django и задавался вопросом, почему он не работает. Один мой друг сказал мне, что эта проблема может возникнуть, если типы mime не установлены на сервере. Но он не был уверен, что это проблема. Но одно можно сказать наверняка.. это как-то связано с сервером.
Ответы
Ответ 1
Попробуйте передать итератор fsock
как параметр HttpResponse()
, а не его метод write()
, который, как я думаю, ожидает строку.
response = HttpResponse(fsock, mimetype=...)
См. http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators
Кроме того, я не уверен, что вы хотите вызвать close
в своем файле перед возвратом response
. Поиграв с этим в оболочке (я не пробовал это в реальном представлении Django), кажется, что response
не получает доступ к файлу до тех пор, пока не будет прочитан сам response
. Попытка прочитать HttpResponse
, созданный с использованием закрытого файла, приводит к ValueError: I/O operation on closed file
.
Итак, вы можете оставить fsock
открытым и позволить сборщику мусора справиться с ним после того, как будет прочитан ответ.
Ответ 2
Может быть, файл содержит некоторые символы, отличные от ascii, которые визуализируются нормально, но не в разработке?
Попробуйте прочитать файл как двоичный:
fsock = open(file_path,"rb")
Ответ 3
Попробуйте отключить "django.middleware.gzip.GZipMiddleware" из вашего MIDDLEWARE_CLASSES в settings.py
У меня была такая же проблема, и после того, как я осмотрел папку промежуточного программного обеспечения, это промежуточное ПО показалось мне виноватым, и удаление его сделало трюк для меня.