2017-06-12 62 views
0

我正在把queryset轉換成csv文件,我甚至得到了迴應。但瀏覽器不下載返回的csv文件。我在鍍鉻。Django HttpResponse生成csv但不下載它

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格式的文本。但它不會觸發下載。

這是我的請求,從反應:

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 OK

日期:星期一,2017年6月12日19時58分03秒GMT

服務器:WSGIServer/0.2 CPython/3.5.3

Content-Type:text/csv

X框選項:SAMEORIGIN

訪問控制允許來源:http://localhost:3000

各不相同:接受,產地

允許:GET,OPTIONS

內容處置:附件;文件名= emailcampaign_export.csv;

緩存控制:無緩存

+0

你的mixin看起來是正確的。你的視圖中定義了'data_format'的位置?你確定它沒有錯誤嗎? – Brobin

+0

我沒有錯過,我忘了在問題中包含該行。我得到了200的http響應,並在響應正文中使用了預期的csv。它只是文件沒有被下載到我的系統。 –

+0

http響應是否具有Content-Disposition標頭? https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition –

回答

0

試試這個:

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