用户完成下载后,Django StreamingHttpResponse删除文件 [英] Django StreamingHttpResponse deleting file after user finishes downloading it
问题描述
使用StreamingHttpResponse时,文件下载完成时,我在跟踪问题.我的意图是在用户下载文件后将其删除.
I am having problem tracking when a file download has been completed when StreamingHttpResponse is used. My intention is to delete the file once it has been downloaded by the user.
执行以下操作会在终端终止服务器方面返回异常.
Doing the following returned an exception in terminal killing the server.
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'
----------------------------------------
有效的方法如下,但是不确定何时删除文件或何时完成下载.最重要的是如何关闭文件:
What works is as follows but am not sure when to delete the file or know when download has been completed. Most importantly how to close the file:
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/')
推荐答案
尝试创建一个类,该类将在文件被gc删除时删除.例如,类似下面的内容可能会起作用:
Try creating a class that will delete the file when it is gc'd. For example, something like the below might work:
class open_then_delete(object):
def __init__(self, filename, mode='rb'):
self.filename = filename
self.file_obj = open(filename, mode)
def __del__(self):
self.close()
def close(self):
if self.file_obj:
self.file_obj.close()
self.file_obj = None
self.cleanup()
def cleanup(self):
if self.filename:
try:
sys.stderr.write('open_then_delete: del ' + self.filename)
os.remove(self.filename)
except:
pass
self.filename = None
def __getattr__(self, attr):
return getattr(self.file_obj, attr)
def __iter__(self):
return iter(self.file_obj)
# 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 = open_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/')
这篇关于用户完成下载后,Django StreamingHttpResponse删除文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!