файл возврата Django через HttpResponse - файл не обслуживается правильно - PullRequest
14 голосов
/ 29 марта 2010

Я хочу вернуть некоторые файлы в 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

Edit: Ошибка на самом деле не ошибка; -)

Это решение работает в производственном режиме на сервере Apache, поэтому с исходным кодом все в порядке.

Во время написания этого вопроса я тестировал его локально на сервере разработки django и удивлялся, почему он не работает. Мой друг сказал мне, что эта проблема может возникнуть, если на сервере не установлены типы mime. Но он не был уверен, что это проблема. Но одно точно ... это как-то связано с сервером.

Ответы [ 3 ]

12 голосов
/ 20 января 2011

Может ли быть, что файл содержит некоторые символы, не относящиеся к ascii, которые хорошо воспроизводятся в работе, но не в разработке?

Попробуйте прочитать файл в двоичном виде:

fsock = open(file_path,"rb")
10 голосов
/ 29 марта 2010

Попробуйте передать итератор 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 открытым и позволить сборщику мусора справиться с ним после прочтения ответа.

1 голос
/ 28 февраля 2012

Попробуйте отключить "django.middleware.gzip.GZipMiddleware" из вашего MIDDLEWARE_CLASSES в settings.py

У меня была та же проблема, и после того, как я осмотрел папку промежуточного программного обеспечения, это промежуточное программное обеспечение показалось мне виновным, и удаление его помогло мне.

...