3

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.

Community
  • 1
  • 1
RknRobin
  • 391
  • 2
  • 6
  • 21
  • What are the permissions for the gcode file? Is django able to actually open that file? – Igl3 Oct 31 '16 at 08:02
  • Django is able to open the file, I need to use my API permissions class from Django Rest Framework. The user needs to have the permission from the permission class, which is already set up. – RknRobin Oct 31 '16 at 08:10
  • Could you share your permission class and maybe a debug trace of calling the endpoint? – Igl3 Oct 31 '16 at 08:11
  • I'm just doing `permission_classes = IsAdmin` which it is. I'm not using special permissions yet but I will be in the near future. How would call the endpoint? – RknRobin Oct 31 '16 at 08:16
  • I guess you defined a view for downloading the file and set up an url. If you did, you can just call it with your browser like "http://:/ If there is any error, you should see the stacktrace in your console log. – Igl3 Oct 31 '16 at 08:22
  • I'm testing all local right now. I've added my view and current testing method to the original question. – RknRobin Oct 31 '16 at 19:25

2 Answers2

2

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.

Anton
  • 504
  • 2
  • 6
  • I was able to run the print command and it displayed the correct file text! I am running by hitting my server with a GET request, and i've added my view to the question. So it seems to be correctly read. – RknRobin Oct 31 '16 at 19:12
0

From some additional research here it seems that since the get_query function is expecting a QuerySet, not a Response object. Thanks to the proposed testing methods above I know my issue is Django Rest Framework viewset, and outside the scope of the original question.

Community
  • 1
  • 1
RknRobin
  • 391
  • 2
  • 6
  • 21