【问题标题】:Django HttpResponse generating csv but not downloading itDjango HttpResponse 生成 csv 但不下载它
【发布时间】:2017-11-14 10:16:41
【问题描述】:

我正在将查询集转换为 csv 文件,我什至得到了回复。但是浏览器没有下载返回的 csv 文件。我在 chrome 上。

class CSVMixin(object):
csv_filename = 'csvfile.csv'

def get_csv_filename(self):
    return self.csv_filename

def render_to_csv(self, queryset):
    response = HttpResponse(content_type='text/csv')
    cd = 'attachment; filename="{0}"'.format(self.get_csv_filename())
    response['Content-Disposition'] = cd

    headers = queryset[0].keys()
    dict_writer = csv.DictWriter(response, fieldnames=headers)

    dict_writer.writeheader()
    dict_writer.writerows(queryset)
    return response

class EmailCampaignViewSet(CSVMixin, OrionAdminModelViewset):
    queryset = MyObject.objects.all()

    pagination_class = DefaultLimitOffsetPagination
    filter_class = EmailCampaignFilter

    @list_route()
    def report(self, request):
        query = self.request.query_params
        data_format = query['data_format'] if query['data_format'] else None

        if data_format == 'csv':
            return self.render_to_csv(queryset)

当我调用报告路由时,我在回复中收到了 csv 格式的文本。但它不会触发下载。

这是我对 react 的要求:

this.getReport = (format="json") => {
        this.setState({btnDisabled: true});
        const requestObj = {
            method: 'GET',
            headers: {
                'Authorization': 'Token ' + this.props.session_token,
                'Content-Type': 'application/json',
            }
        };

        const uri = new URI(`${API_ENDPOINT}/email-campaign/report`);
        const campaigns = this.state.campaignList.map((campaign)=>(
            campaign.value
        ));
        uri.setSearch({
            campaigns: [campaigns],
            date_from: stringToDateISOString(this.state.dateFrom),
            date_to: stringToDateISOString(this.state.dateTo),
            data_format: format,
        });
        return fetch(uri.toString(), requestObj).then(restJSONResponseToPromise).then(responseJSON => {
            if (responseJSON.results){
                this.setState({report: responseJSON.results, btnDisabled: false});
            }
        }, (response) => {
            clearSessionIfInvalidToken(this.props.clearSession);
            this.setState({btnDisabled: false});
        });
    }

响应标头:

HTTP/1.0 200 正常

日期:2017 年 6 月 12 日星期一 19:58:03 GMT

服务器:WSGIServer/0.2 CPython/3.5.3

内容类型:文本/csv

X-Frame-选项:SAMEORIGIN

访问控制允许来源:http://localhost:3000

变化:接受,来源

允许:GET、OPTIONS

Content-Disposition:附件;文件名=emailcampaign_export.csv;

缓存控制:无缓存

【问题讨论】:

  • 你的 mixin 看起来是正确的。 data_format 在您的视图中定义在哪里?你确定它没有出错吗?
  • 我没有出错,我忘记在问题中包含该行。我得到了 200 的 http 响应,响应正文上有预期的 csv。它只是没有下载到我的系统中的文件。
  • http 响应是否有 Content-Disposition 标头? developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…
  • 是的,它具有以下标头:HTTP/1.0 200 OK 日期:星期一,2017 年 6 月 12 日 19:58:03 GMT 服务器:WSGIServer/0.2 CPython/3.5.3 内容类型:text/csv X-Frame-Options: SAMEORIGIN Access-Control-Allow-Origin: localhost:3000 Vary: Accept, Origin Allow: GET, OPTIONS Content-Disposition: attachment;文件名=emailcampaign_export.csv;缓存控制:无缓存
  • 我会在问题中添加 react 和 javascript 标签。我在这些方面没有经验,如果正确返回响应,这听起来可能会导致问题。

标签: python django csv django-rest-framework httpresponse


【解决方案1】:

试试这个:

from cStringIO import StringIO

def render_to_csv(self, queryset):
    file_io = StringIO()
    headers = queryset[0].keys()
    dict_writer = csv.DictWriter(file_io, fieldnames=headers)
    dict_writer.writeheader()
    dict_writer.writerows(queryset)
    response = HttpResponse(file_io.getvalue(), content_type='text/csv')
    file_io.close()
    cd = 'attachment; filename="{0}"'.format(self.get_csv_filename())
    response['Content-Disposition'] = cd
    return response

【讨论】:

    猜你喜欢
    • 2013-12-16
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 2019-04-02
    • 2013-08-10
    • 1970-01-01
    相关资源
    最近更新 更多