How to serve created tempfile in django

I have a remote storage project which, when a user requests his file, the django server extracts and saves the file locally (for some processing) as a temporary file, and then serves it to the user with the mod x-sendfile file. I want the temporary file to be definitely deleted after it is sent to the user.

The documentation says that the argument to delete NamedTemporaryFile, if set Falsecauses the file to be deleted, after that all the links disappeared. But when the user is served by a temporary file, it is not deleted. If I set delete = True on boot, I get "The requested URL / ServeSegment / Test.jpg / was not found on this server."

Here is a list to view user files:

def file_profile(request):
    obj = MainFile.objects.filter(owner=request.user)
    context = {'title': 'welcome',
               'obj': obj
               }
    return render(request, 'ServeSegments.html', context=context)

This is a view that retrieves, temporarily saves, and serves the requested file:

def ServeSegment(request, segmentID):    
    if request.method == 'GET':    
        url = 'http://192.168.43.7:8000/foo/'+str(segmentID)
        r = requests.get(url, stream=True)
        if r.status_code == 200:
            with tempfile.NamedTemporaryFile(dir=
        '/tmp/Files', mode='w+b') as f:
                for chunk in r.iter_content(1024):
                    f.write(chunk)        
            response = HttpResponse()
            response['Content-Disposition'] = 'attachment; segmentID={0}'.format(f.name)
            response['X-Sendfile'] = "{0}".format(f.name)
            return response
        else:
            return HttpResponse(str(segmentID))

I think if I could get the answer back inside using the instruction, and after that the last fragment was written, it would work the way I want, but I did not find a solution on how to determine if we are in the last loop (without being hacked).

What should I do to maintain a temporary file and delete it right after?

+4
source share
3 answers

, tempfile, . , with. delete=False . , .

, StreamingHttpResponse FileResponse. , , " ( )", .

+2

( Cyrbil's), :

import os
import tempfile
from django.http import FileResponse

def my_view(request):
    try:
        tmp = tempfile.NamedTemporaryFile(delete=False)
        with open(tmp.name, 'w') as fi:
            # write to your tempfile, mode may vary
        response = FileResponse(open(tmp.name, 'rb'))
        return response
    finally:
        os.remove(tmp.name)
+2

. , with NamedTeoraryFile . .

f.seek(0)
return FileResponse(f, as_attachment=True, filename=f.name)

, , .

, , .

Judging by other answers, the signals seemed a reasonable decision, however, to transfer data, it was necessary to change the protected members. I was not sure how much this would be supported in the future. I also found that the whp solution does not work in the current version of Django. The most promising version that I could come up with was a monkey that corrected the output of the file, so the file was deleted when it was closed. Django closes the file descriptors at the end of the file upload, and I do not see this change.

def my_view(request):
  tmp = tempfile.NamedTemporaryFile(delete=False)

  try:
    # write file tmp (remember to close if re-opening)
    # after write close the file (if not closed)      

    stream_file = open(tmp.name, 'rb')

    # monkey patch the file
    original_close = stream_file.close

    def new_close():
        original_close()
        os.remove(tmp.name)

    stream_file.close = new_close

    # return the result
    return FileResponse(stream_file, as_attachment=True, filename='out.txt')
  except Exception:
      os.remove(output.name)
      raise
0
source

Source: https://habr.com/ru/post/1619688/


All Articles