2017-08-08 21 views
0

DjangoのStreamingHttpResponseを使用して、大規模なCSVファイルをオンザフライでストリーミングしています。 the docsによると、反復子は、応答のstreaming_contentパラメータに渡されます。ストリームを手動でStreamingHttpResponse(Django)に追加する

import csv 
from django.http import StreamingHttpResponse 

def get_headers(): 
    return ['field1', 'field2', 'field3'] 

def get_data(item): 
    return { 
     'field1': item.field1, 
     'field2': item.field2, 
     'field3': item.field3, 
    } 

# StreamingHttpResponse requires a File-like class that has a 'write' method 
class Echo(object): 
    def write(self, value): 
     return value 


def get_response(queryset): 
    writer = csv.DictWriter(Echo(), fieldnames=get_headers()) 
    writer.writeheader() # this line does not work 

    response = StreamingHttpResponse(
     # the iterator 
     streaming_content=(writer.writerow(get_data(item)) for item in queryset), 
     content_type='text/csv', 
    ) 
    response['Content-Disposition'] = 'attachment;filename=items.csv' 

    return response 

私の質問は:どのように私は手動でCSVライターに行を書き込むことができますか? writer.writerow(data)またはwriter.writeheader()(内部でwriterow()を呼び出す)を手動で呼び出すと、データセットに書き込まれないようになり、streaming_contentからの生成/ストリームデータのみが出力データセットに書き込まれます。

答えて

1

答えが代わりに(StreamingHttpResponseのstreaming_content引数内の)その場でそれらを計算し、対応する行を書き込むために、我々が作成した擬似バッファ(エコークラス)を使用する発電機能付きの結果が得られている。

import csv 
from django.http import StreamingHttpResponse 

def get_headers(): 
    return ['field1', 'field2', 'field3'] 

def get_data(item): 
    return { 
     'field1': item.field1, 
     'field2': item.field2, 
     'field3': item.field3, 
    } 

# StreamingHttpResponse requires a File-like class that has a 'write' method 
class Echo(object): 
    def write(self, value): 
     return value 

def iter_items(items, pseudo_buffer): 
    writer = csv.DictWriter(pseudo_buffer, fieldnames=get_headers()) 
    yield pseudo_buffer.write(get_headers()) 

    for item in items: 
     yield writer.writerow(get_data(item)) 

def get_response(queryset): 
    response = StreamingHttpResponse(
     streaming_content=(iter_items(queryset, Echo())), 
     content_type='text/csv', 
    ) 
    response['Content-Disposition'] = 'attachment;filename=items.csv' 
    return response 
関連する問題