如何在Python Django中保存POST变量的数据并重新加载到响应中?

3 投票
1 回答
1919 浏览
提问于 2025-04-17 07:14

我遇到了一个问题 - 我正在使用 Python 2.6 和 Django 1.3,我需要接收一个名为 'f' 的 POST 变量,这个变量里包含二进制数据。接下来,我需要把这些数据保存到一个文件里

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

把数据保存到文件里可能会更简单,也更省内存。就像@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

在你的情况下,你可能需要手动设置文件的类型,也可以试试application/octet-stream。主要的区别在于,你是从file.read()中传递“字符串”,而不是直接传递文件的句柄。请注意:如果你使用read(),那就会把整个文件都加载到内存中。

关于如何将迭代器传递给HttpResponse的更多信息,可以查看这个链接。我可能说错了,但我觉得你可以省略内容类型的设置。

撰写回答