在django中返回HttpResponse后删除tmp文件

Oli*_*Oli 9 python django

我正在使用以下django/python代码将文件流式传输到浏览器:

wrapper = FileWrapper(file(path))
response = HttpResponse(wrapper, content_type='text/plain')
response['Content-Length'] = os.path.getsize(path)
return response
Run Code Online (Sandbox Code Playgroud)

返回响应后有没有办法删除文件?使用回调函数还是什么?我可以创建一个cron来删除所有tmp文件,但如果我可以流式传输文件并从同一请求中删除它们,它会更整洁.

小智 11

您可以使用NamedTemporaryFile:

from django.core.files.temp import NamedTemporaryFile
def send_file(request):
    newfile = NamedTemporaryFile(suffix='.txt')
    # save your data to newfile.name
    wrapper = FileWrapper(newfile)
    response = HttpResponse(wrapper, content_type=mime_type)
    response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(modelfile.name)
    response['Content-Length'] = os.path.getsize(modelfile.name)
    return response
Run Code Online (Sandbox Code Playgroud)

驱逐newfile对象后,应删除临时文件.


le-*_*ude 6

供将来参考:我刚刚遇到了无法使用临时文件进行下载的情况。但我仍然需要在之后删除它们;这就是我的做法(我真的不想依赖 cron jobs 或 celery 或 wossnames,它是一个非常小的系统,我希望它保持这种状态)。

def plug_cleaning_into_stream(stream, filename):
    try:
        closer = getattr(stream, 'close')
        #define a new function that still uses the old one
        def new_closer():
            closer()
            os.remove(filename)
            #any cleaning you need added as well
        #substitute it to the old close() function
        setattr(stream, 'close', new_closer)
    except:
        raise
Run Code Online (Sandbox Code Playgroud)

然后我只是将用于响应的流插入其中。

def send_file(request, filename):
    with io.open(filename, 'rb') as ready_file:
        plug_cleaning_into_stream(ready_file, filename)
        response = HttpResponse(ready_file.read(), content_type='application/force-download')
        # here all the rest of the heards settings
        # ...
        return response
Run Code Online (Sandbox Code Playgroud)

我知道这又快又脏,但它确实有效。我怀疑这对于每秒处理数千个请求的服务器来说是否高效,但这不是我这里的情况(最多一分钟几十个)。

编辑:忘记准确地说,我正在处理非常非常大的文件,这些文件在下载过程中无法放入内存。这就是为什么我使用 a BufferedReader(这就是下面的io.open())