如何在 Django 中下载临时文件?

Posted

技术标签:

【中文标题】如何在 Django 中下载临时文件?【英文标题】:How can I download a temporary file in Django? 【发布时间】:2017-03-13 07:22:03 【问题描述】:

我正在学习如何在 Django 中提供临时文件,即使在阅读了docs 之后,我在完成这一切时也遇到了一些麻烦。这些文件是根据用户输入临时动态生成的。

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

上面的代码应该将我的临时 gcode 文件从我的服务器放入一个 HttpResponse 对象,并且返回函数应该下载该文件。它甚至像下载一样变慢,但是一旦完成就没有文件了。

This question 提供了大部分有用的信息,this one 也很有帮助,但我无法让它工作,也不知道如何测试它。我不确定移动到 apache 是否合适,因为我有用户权限问题,并且这些文件在下载后会立即删除。我已经检查过“gcode”是目录 url,并且 gcode content_type 应该是 text/plain。所以基本上,我怎样才能让我的回复真正下载?

编辑1

这里是完整的代码,不仅仅是有问题的部分。

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

我正在使用 Django Rest Framework 并尝试从我的 API 获取请求创建动态响应,以对 URL 中给出的参数做出反应。所以我发送了一个 get 请求,将变量作为参数传递,它基于这些变量创建一个文件,最后将创建的文件发回。除了最后的实际文件下载之外,所有这些都已经有效。 get 请求返回 HTTP 500 错误。

【问题讨论】:

gcode文件的权限是什么? django 真的能打开那个文件吗? Django 能够打开文件,我需要使用 Django Rest Framework 中的 API 权限类。用户需要拥有已经设置好的权限类的权限。 您能否分享您的权限类以及调用端点的调试跟踪? 我只是在做permission_classes = IsAdmin 它就是这样。我还没有使用特殊权限,但我会在不久的将来使用。如何调用端点? 我猜你定义了一个用于下载文件的视图并设置了一个 url。如果你这样做了,你可以用你的浏览器调用它,比如“http://:/ 如果有任何错误,你应该在控制台日志中看到堆栈跟踪。 【参考方案1】:

为了测试,你可以创建这样的视图:

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

如果你在 shell (django) 中测试:

print(response.content)

在您的代码末尾确保您的文件已被读取。

【讨论】:

我能够运行打印命令并且它显示了正确的文件文本!我通过使用 GET 请求访问我的服务器来运行,并且我已将我的观点添加到问题中。所以它似乎被正确读取了。【参考方案2】:

从一些额外的研究here 看来,由于 get_query 函数需要一个 QuerySet,而不是一个 Response 对象。感谢上面提出的测试方法,我知道我的问题是 Django Rest Framework 视图集,并且超出了原始问题的范围。

【讨论】:

以上是关于如何在 Django 中下载临时文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何查找电脑中的临时文件夹

在 Django Celery 结果中使用临时文件

如何使用 heroku 临时文件系统

使用 NSURLSession 如何在取消下载任务时获取接收到的数据或临时文件位置

Django Admin - 创建“临时”条目

请问下,我想用java实现下载excel表格,思路是先在临时文件里生成临时excel文件,但是不知