【问题标题】:how do i use FileResponse.set_headers() in my django application to enable .mp3 file download如何在我的 django 应用程序中使用 FileResponse.set_headers() 来启用 .mp3 文件下载
【发布时间】:2020-10-25 22:49:07
【问题描述】:

我正在尝试使用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)
 

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

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

`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' object has no attribute 'filename'。 请任何人都可以帮助我,或者如果在 django 中有另一种方法可以做到这一点,我将非常感谢某人的帮助。或者我可以在 django、Nginx 或 Javascript 中设置我的 Content-Disposition 的任何其他可能方式。

【问题讨论】:

    标签: python django content-disposition


    【解决方案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")
    
    • 最后,当文件被浏览器抛出时:

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

    你好,

    【讨论】:

    • 您好,亲爱的,我正在尝试检查代码,但是您从哪里导入“utldol”?
    • 嗨@Manuel Lazo 感谢您的帮助,但是我从哪里导入 utldol
    【解决方案2】:

    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”函数读取。

    【讨论】:

      【解决方案3】:

      这个问题没有答案,因为方法 '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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-13
        • 2016-10-31
        • 1970-01-01
        • 1970-01-01
        • 2011-01-30
        • 1970-01-01
        • 2022-01-22
        • 2011-04-08
        相关资源
        最近更新 更多