用户完成下载后,Django StreamingHttpResponse删除文件

时间:2015-12-08 06:17:15

标签: python django

当使用StreamingHttpResponse时,我在完成文件下载时遇到问题跟踪。我的目的是在用户下载文件后删除该文件。

执行以下操作会在杀死服务器的终端中返回异常。

def down(request, file_name):
    if request.method == 'GET':
        if file_name:
            import os
            fh = get_object_or_404(FileHandler, filename=file_name)
            csv_path = os.path.join(fh.path, fh.filename)
            csv_file = open(csv_path)
            response = StreamingHttpResponse(csv_file, content_type='text/csv')
            response['Content-Disposition'] = 'attachment; filename="{}"'.format(fh.filename)
            csv_file.close()
            # I can now delete the file using os.remove(csv_path). Not sure since response has not been returned
            return response
    return HttpResponseRedirect('/b2b/export/')
追回:

----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 59899)
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 599, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/Users/Michael/.virtualenvs/scrape/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 102, in __init__
    super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/Users/Michael/.virtualenvs/scrape/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 182, in handle
    handler.run(self.server.get_app())
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/handlers.py", line 92, in run
    self.close()
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/simple_server.py", line 33, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
----------------------------------------

有效的方法如下,但不确定何时删除文件或知道下载何时完成。最重要的是如何关闭文件:

def down(request, file_name):
    if request.method == 'GET':
        if file_name:
            import os
            fh = get_object_or_404(FileHandler, filename=file_name)
            csv_path = os.path.join(fh.path, fh.filename)

            response = StreamingHttpResponse(open(csv_path), content_type='text/csv')
            response['Content-Disposition'] = 'attachment; filename="{}"'.format(fh.filename)
            return response
    return HttpResponseRedirect('/b2b/export/')

2 个答案:

答案 0 :(得分:0)

尝试创建一个类,当它是gc&d时,将删除该文件。例如,类似下面的内容可能会起作用:

# WARNING! Untested code
# ----------------------

# new class that removes file upon garbage collection
class use_then_delete(object):
    def __init__(self, filename):
        self.filename = filename

    def open(self):
        if self.fd == None:
            self.fd = open(self.filename)
        return self.fd

    def __del__(self):
        if self.fd != None:
            self.fd.close()
            os.remove(self.filename)

# below is your code, modified to use use_then_delete
def down(request, file_name):
    if request.method == 'GET':
        if file_name:
            import os
            fh = get_object_or_404(FileHandler, filename=file_name)
            csv = use_then_delete(os.path.join(fh.path, fh.filename))

            response = StreamingHttpResponse(csv.open(), content_type='text/csv')
            response['Content-Disposition'] = 'attachment; filename="{}"'.format(fh.filename)
            return response
    return HttpResponseRedirect('/b2b/export/')

答案 1 :(得分:0)

我已经通过@mwag尝试了以上建议;但是使用FileWrapper。

就我而言,想压缩目录并在下载完成后删除存档。

/bin/sh -c ASPNETCORE_URLS\=http://\*:\30695\ dotnet\ sitehidamek.dll