RknRobin RknRobin - 1 month ago 8
Python Question

How can I download a temporary file in Django?

I'm learning how to serve temporary files in Django, and even after reading the docs I'm having some trouble finishing it all up. These files are dynamically generated temporarily from user input.

def get_queryset(self):
gcode = "/home/bradman/Documents/Programming/DjangoWebProjects/3dprinceprod/fullprince/media/uploads/tmp/skull.gcode"
test_file = open(gcode, 'r')

response = HttpResponse(test_file, content_type='text/plain')
response['Content-Disposition'] = "attachment; filename=%s.gcode" % title
print (response)
return response


The code above should place my temporary-gcode file from my server into an HttpResponse object, and the return function should download the file. It even slows down like its downloading, but there is no file once it's finished.

This question provided most of the useful info and this one was helpful as well, but I can't get it working and don't know how else to test it. I'm not sure if moving to apache or something is appropriate since I have user permission issues and these files are immediately deleted after downloaded. I've checked that "gcode" is the directory url, and gcode content_type should be text/plain. So basically, how can I make my response actually download?

Edit1

Here is the full code, not just the problematic section.

class SubFileViewSet(viewsets.ModelViewSet):
queryset = subfiles.objects.all()
serializer_class = SubFilesSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)

def perform_create(self, serializer):
serializer.save(owner=self.request.user)

def get_queryset(self):
req = self.request
make = req.query_params.get('make')
model = req.query_params.get('model')
plastic = req.query_params.get('plastic')
quality = req.query_params.get('qual')
filenum = req.query_params.get('fileid')
hotend = req.query_params.get('hotendtemp')
bed = req.query_params.get('bedtemp')


if make and model and plastic and quality and filenum:

filepath = subfiles.objects.values('STL', 'FileTitle').get(fileid = filenum)

path = filepath['STL']
title = filepath['FileTitle']

gcode = TheMagic(
make=make,
model=model,
plastic=plastic,
qual=quality,
path=path,
title=title,
hotendtemp=hotend,
bedtemp=bed)

test_file = open(gcode, 'r')
response = HttpResponse(test_file, content_type='text/plain')
response['Content-Disposition'] = "attachment; filename=%s.gcode" % title
print (response.content)
return response

else:
print ('normal or non complete download')
return self.queryset


I'm using Django Rest Framework and trying to create a dynamic response from my API get request to react to parameters given in the URL. So I send a get request passing variables as parameters, it creates a file based on those variables, and lastly sends back the created file. All of this already works except the actual file download at the end. The get request returns an HTTP 500 error.

Answer

For test, you can create view like that:

def download_file(request):
    gcode = "/home/bradman/Documents/Programming/DjangoWebProjects/3dprinceprod/fullprince/media/uploads/tmp/skull.gcode"
    resp = HttpResponse('')

    with  open(gcode, 'r') as tmp:
        filename = tmp.name.split('/')[-1]
        resp = HttpResponse(tmp, content_type='application/text;charset=UTF-8')
        resp['Content-Disposition'] = "attachment; filename=%s" % filename

    return resp

If you test in shell (django):

print(response.content)

At end of your code to ensure that your file has been read.

Comments