Как сохранить данные файла из переменной POST и загрузить их обратно в ответ в Python Django? - PullRequest
3 голосов
/ 28 ноября 2011

У меня такая проблема - я использую Python 2.6 / Django 1.3, и мне нужно принять в качестве переменной POST ключ 'f', который содержит двоичные данные . После этого мне нужно сохранить данные в файл.

POST

T$topX$objectsX$versionY$archiverО©ҐR$0О©ҐО©ҐО©Ґull_=<---------------------- content of file -------------------->О©ҐО©Ґ_NSKeyedArchive(258:=CО©ҐО©Ґ

Код

from django.core.files.storage import default_storage
from django.core.files.base import ContentFile

def save(request):
    upload_file = request.POST['f']
    save_path = default_storage.save('%s%s' % (save_dir, filename),
        ContentFile(upload_file))

Когда я пытаюсь сделать

nano /tmp/myfile.zip 

Возвращает данные типа

T^@^@^@$^@^@^@t^@^@^@o^@^@^@p^@^@^@X^@^@^@$^@^@^@o^@^@^@b^@^@^@j^@^@^@e^@^@^@c^@^@^@t^@^@^@s^@^@^@X^@^@^@$^@^@^@v^@^@^@e^@^@^@r^@^@^@s^@^@^@i^@^@$

Когда это будет сделано, я собираюсь прочитать сохраненный файл

def read(request):
    user_file = default_storage.open(file_path).read()
    file_name = get_filename(file_path)
    response = HttpResponse(user_file, content_type = 'text/plain', 
               mimetype = 'application/force-download')
    response['Content-Disposition'] = 'attachment; filename=%s' % file_name
    response['Content-Length'] = default_storage.size(file_path)

    return response

В случае, когда я пишу

print user_file

Возвращает правильные данные, но когда я возвращаю HttpResponse, он имеет данные, отличные от источника

1 Ответ

0 голосов
/ 02 декабря 2011

Вероятно, было бы проще и более эффективно использовать память, если вы просто сохраняете данные в файл и, как сказал @keckse, позволяете браузеру транслировать их. Django очень неэффективен в потоковой передаче данных. Все будет зависеть от размера данных. В любом случае, если вы хотите транслировать его с помощью django, это можно сделать так:

from django.http import HttpResponse
import os.path
import mimetypes


def stream(request, document, type=None):
    doc = Document.objects.get(pk=document)

    fsock = open(doc.file.path,"r")

    file_name = os.path.basename(doc.file.path)
    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
    return response

В вашем случае вы можете захотеть установить тип mime вручную, вы также можете попробовать application / octet-stream. Основное отличие итераторов заключается в том, что вы передаёте «строку» из file.read () вместо дескриптора в файл напрямую. Обратите внимание: если вы используете read (), вы загрузите весь файл в память.

Подробнее о передаче итераторов в HttpResonse. И я могу ошибаться, но я думаю, что вы можете отбросить тип контента .

...