Получение пустого файла, когда обслуживается Django - PullRequest
2 голосов
/ 05 января 2012

У меня есть следующий код для управления загрузкой файлов через 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 response

К сожалению, мой браузер получает пустой файл при загрузке.

Печатный ответ кажется правильным:

Content-Length: 3906
Content-Type: text/plain
Content-Disposition: attachment; filename=toto.txt

blah blah ....

У меня похожий код, работает нормально. Я не понимаю, в чем может быть проблема. Есть идеи?

PS: я проверил предложенное решение здесь и получил то же поведение

Обновление: Замена wrapper = FileWrapper(file) на wrapper = file.read(), кажется, решает проблему

Обновление: если я прокомментирую print response, я получу похожую проблему :. файл пуст Единственная разница: FF обнаруживает размер в 20 байт. (файл больше этого)

Ответы [ 2 ]

1 голос
/ 05 января 2012

Файловый объект является целочисленным и генератором.Это может быть прочитано только один раз, прежде чем исчерпаны.Затем вам нужно создать новый метод использования, чтобы снова начать с начала объекта (например: seek()).

read() возвращает строку, которую можно прочитать несколько раз безлюбая проблема, вот почему она решает вашу проблему.

Так что просто убедитесь, что если вы используете файл, подобный объекту, вы не прочитаете его дважды подряд.EG: не печатать, а затем вернуть.

0 голосов
/ 05 января 2012

Из документации Django :

FieldFile.open (mode = 'rb') ведет себя как стандартный Python open () метод и открывает файл, связанный с этим экземпляром в режиме указывается режимом.

Если он работает как питон open, тогда он должен возвращать файл-объект и должен использоваться следующим образом:

f = file.open('rb')
wrapper = FileWrapper(f)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...