2015-12-08 95 views
2

使用StreamingHttpResponse時,我在文件下載完成時遇到了問題跟蹤。我的目的是在用戶下載文件後刪除文件。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/') 

回答

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/')