【问题标题】:Django output csv file, filename is not setting as the value of Content-DispositionDjango 输出 csv 文件,文件名未设置为 Content-Disposition 的值
【发布时间】:2019-11-28 08:11:03
【问题描述】:

我想在 django 项目中下载具有自定义文件名的 csv 文件,但不知何故,下载的文件名仅显示为“download.csv”,而不是使用 Content-Disposition 中的文件名值。我也尝试将csv_response['Content-Disposition'] 打印出来,但我得到了一个非常奇怪的字符串=?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9Iuivvueoi+aKpeWQjeaDheWGtV8yMDE5MTEyODA3NDI0Ny5jc3Yi?=

代码 sn-p 是:

@action(detail=False, methods=['GET'])
def download(self, request):
    registrations = self.filter_queryset(self.get_queryset())

    csv_response = HttpResponse(content_type='text/csv')
    csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{time}.csv"'.format(
        time=time.strftime("%Y%m%d%H%M%S", time.localtime())
    )

    writer = csv.writer(csv_response)
    writer.writerow([
        some content,
    ])

    for registration in registrations:
        term_title = '{order} th'.format(order=registration.term.order)
        course_title = registration.course.title

        writer.writerow([
            registration.user.email,
            course_title,
            term_title,
            str(registration.confirmation_code),
            str(registration.payment_due),
            str(registration.payment_paid),
            str(registration.source),
            str(registration.created_at),
            str(registration.updated_at),
            str(registration.payment_source),
        ])

    return csv_response

我使用的 django 是 2.2

任何想法为什么会发生这种情况?我是新手。 提前谢谢

chrome 开发工具中的响应头:

【问题讨论】:

  • 如果所有预期的标头设置正确,您是否检查了您的客户端(例如,在 chrome 中使用 dev tools)?
  • @mfrackowiak 下载文件后,我发现 Content-Disposition 未包含在响应标头中,但我不明白为什么。文件没问题。
  • 我认为你不需要文件名周围的引号,我建议你删除它并重试...'attachment;文件名=some_custom_name_{time}.csv'
  • @prime_hit 不,这不是原因,我之前尝试过。是编码问题。

标签: django


【解决方案1】:

我按照以下帖子中的答案解决了这个问题: HttpResponse Django does not change file name

我猜是因为Content-Disposition的字符串需要编码,如果没有,那么不知何故无法对其进行操作,通过使用urlquote,它就解决了。 关于urlquote的解释是here

更新: 此外,在不导入 urlquote 的情况下解决此问题的更简单方法是添加 encode(),如下所示:

csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{time}.csv"'.format(
            time=time.strftime("%Y%m%d%H%M%S", time.localtime())
        ).encode()

【讨论】:

  • 您是否尝试使用一些普通字符串,例如“Abc.csv”?你能检查一下传递一个硬编码的值是否能解决问题吗?
  • @NalinDobhal 如果不使用urlquote,则它不起作用。
【解决方案2】:

改成这样:

csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{}.csv"'.format(
            time.strftime("%Y%m%d%H%M%S", time.localtime())
        )

【讨论】:

  • 我在发帖之前已经尝试过了,但它不起作用。而且我下载文件后发现响应头中不包含 Content-Disposition。
猜你喜欢
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 2013-12-06
  • 2021-12-22
  • 2022-07-06
  • 2011-11-07
  • 1970-01-01
相关资源
最近更新 更多