2

我正在尝试使用FileResponse.set_header()Content-Disposition设置为attachment,以便可以在我的 python/django 支持的网站中下载音频文件而不是在浏览器上播放。有什么办法可以实现下面的代码以使其工作?

song = models.song.objects.filter(id__exact=song_id).first()
file_name = ntpath.basename(song.songfile.url)
content_type = 'audio/mpeg'
with open(identify_song.songfile.path, 'rb') as my_f:
      file_like = my_f
response = FileResponse(my_f,  content_type=content_type, as_attachment=True, filename="{}".format(file_name))
response['Content-Disposition'] = 'attachment; filename="{}"'.format(file_name)
 size = response['Content-Length'] = os.path.getsize(identify_song.songfile.path)
 #print(file_name)
 return(response)
 

这段代码没有给我任何错误,但它不起作用

所以我FileResponse.set_header()在 django 文档中发现了,所以我尝试像这样使用它。

`song = models.song.objects.filter(id__exact=song_id).first()
file_name = ntpath.basename(song.songfile.url)
FileResponse.set_headers(file_name, filelike='audio/mpeg', as_attachment=True)`

然后我得到一个错误AttributeError:'str'对象没有属性'filename'。请任何人都可以帮助我,或者如果在 django 中有另一种方法可以做到这一点,我将非常感谢某人的帮助。或者我可以在 django、Nginx 或 Javascript 中设置我的Content-Disposition的任何其他可能方式。

4

3 回答 3

1

为了下载生成的文件,我整天都在使用这个功能,让我分享一下我是如何做到的,它就像一个魅力。

文档:https ://docs.djangoproject.com/en/3.0/ref/request-response/

http 标头“内容处置”:https ://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

try:
    wdata = request.GET
    download = wdata.get("download") or ''
    allowed_params = [
        'template', 'bases',
    ]
    if download in allowed_params:
        out, err = utldol.download_file(download, request)
        if err:
            raise ValueError(str(err))
    else:
        raise ValueError(str('Parameter not recognized'))

    file = FileResponse(
        out.get("file"), filename=out.get("filename"),
    )
    file['Content-Disposition'] = 'attachment; filename="{}"'.format(
        out.get("filename")
    )
    return file

except Exception as ex:
    return HttpResponseBadRequest(str(ex))
  • 参数“file”包含文件实例: open('file.txt','rb') :
out.get("file")
  • 参数“filename”包含文件的名称
out.get("filename")
  • 最后,当文件被浏览器抛出时:

在此处输入图像描述

希望我的经验对您有所帮助,任何意见,请让我知道。

问候,

于 2020-07-09T01:02:47.807 回答
0

utldol 它是一个包含函数的 python 文件,它生成一个 xls 文件。该函数返回如下:

outcome, error = None, None
try:
     ........
     ........
     file = open(output.get("filedir"), 'rb')
     outcome = {
          "file": file, "filename": output.get("filename"),
      }
except Exception as ex:
    error = str(ex)
return [outcome, error]
  • 输出包含生成的 xls 文件的完整路径,然后由“open”函数读取。
于 2020-07-11T14:37:49.797 回答
0

这个问题没有答案,因为方法 'FileResponse.set_header()' 只能用像对象这样的文件来调用,如果你使用非常奇特的文件类型,它会对标题进行一些猜测,这些猜测是不可靠的。至少你可以覆盖这个函数,它什么都不返回,只设置标题信息,或者你可以自己在代码中完成这个小任务。这是我使用内存中字符串缓冲区的示例。

            filename = "sample.creole"
            str_stream = StringIO()
            str_stream.write("= Some Creole-formated text\nThis is creole content.")
            str_stream.seek(0)
            response = FileResponse(str_stream.read())
            response.headers['Content-Disposition'] = 'attachment; filename={}'.format(filename)
            response.headers['Content-Type'] = 'application/creole'
            return response

使用这种方法,您仍然可以使用默认的“FileResponse.set_header()”功能来设置正常工作的“Content-Length”。由于“as_attachment”和“filename”等其他“FileResponse”参数不可靠。可能没有人注意到,因为很少使用“FileResponse”,事实上,使用“HttpResponse”可以实现相同的功能。

            response = HttpResponse(content_type='application/creole')
            response.headers['Content-Disposition'] = 'attachment; filename={}'.format(filename)
            response.write(str_stream.read())
            return response
于 2021-05-19T13:58:50.317 回答