장고에서 CSV 출력하기

이 문서에서는 Django 보기를 사용하여 CSV(Comma Separated Values)를 동적으로 출력하는 방법에 대해 설명합니다. 이를 위해 Python CSV 라이브러리 또는 Django 템플릿 시스템을 사용할 수 있습니다.

파이썬 CSV 라이브러리 사용하기

Python은 CSV 라이브러리인 :mod:〉csv’와 함께 제공됩니다. Django와 함께 사용하기 위한 핵심은 :mod:〉csv〉 모듈의 CSV-생성 기능이 파일 같은 개체에 작용하고 Django의 :class는 다음과 같습니다.〉~django.the〉 입니다.HttpResponse〉 객체는 파일 유사 객체입니다.

여기 예제가 있습니다:

import csv
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    writer = csv.writer(response)
    writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
    writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])

    return response

코드와 코멘트는 자명해야 하지만 몇 가지 사항은 언급할 가치가 있습니다.

  • 응답에는 특수 MIME 유형인 :mimtype:〉text/csv’가 있습니다. 이것은 문서가 HTML 파일이 아닌 CSV 파일임을 브라우저에 알려줍니다. 이 기능을 해제하면 브라우저가 출력을 HTML로 해석하여 브라우저 창에서 보기 흉하고 무서운 단어를 만들 수 있습니다.
  • 이 응답에는 CSV 파일의 이름이 포함된 《Content-Disposition》 헤더가 추가됩니다. 이 파일 이름은 임의이므로 원하는 대로 불러 주십시오. 브라우저가 《다른 이름으로 저장…》에서 사용합니다.대화 상자 등입니다.
  • 《csv.writer》에 대한 첫 번째 논거로 《대응》을 전달함으로써 CSV 세대 API에 연결할 수 있습니다. 《csv.writer》 기능은 파일 같은 객체를 기대하며 :class는 다음과 같습니다.〉~django.the〉 입니다.HttpResponse〉 객체가 빌에 맞습니다.
  • CSV 파일의 각 행에 대해 〈〉writer〉〉로 전화하십시오.》글쓴다》는 뜻으로 《표절할 수 있다》라는 말을 씁니다.
  • CSV 모듈은 견적을 처리하므로 따옴표 또는 쉼표가 포함된 문자열을 이스케이프할 필요가 없습니다. 《원래의 조건》을 넘기면 옳은 일을 할 수 있을 것입니다.

대용량 CSV 파일들을 스트리밍하기

매우 큰 응답을 생성하는 보기를 처리할 때 Django의 :class:를 사용하는 것을 고려할 수 있습니다.〉~django.the〉 입니다.대신 스트리밍HttpResponse’입니다. 예를 들어, 생성하는 데 시간이 오래 걸리는 파일을 스트리밍하면 서버가 응답을 생성하는 동안 시간 초과되었을 수 있는 연결을 로드 밸런서가 삭제하지 않도록 방지할 수 있습니다.

이 예에서는 Python 생성기를 최대한 활용하여 대형 CSV 파일의 어셈블리 및 전송을 효율적으로 처리합니다.

import csv

from django.http import StreamingHttpResponse

class Echo:
    """An object that implements just the write method of the file-like
    interface.
    """
    def write(self, value):
        """Write the value by returning it, instead of storing in a buffer."""
        return value

def some_streaming_csv_view(request):
    """A view that streams a large CSV file."""
    # Generate a sequence of rows. The range is based on the maximum number of
    # rows that can be handled by a single sheet in most spreadsheet
    # applications.
    rows = (["Row {}".format(idx), str(idx)] for idx in range(65536))
    pseudo_buffer = Echo()
    writer = csv.writer(pseudo_buffer)
    response = StreamingHttpResponse((writer.writerow(row) for row in rows),
                                     content_type="text/csv")
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
    return response

템플릿 시스템 사용하기

또는 :doc을 사용할 수 있습니다.CSV를 생성하기 위한 〈장고 템플릿 시스템’입니다. 이는 편리한 Python:mod:〉csv〉 모듈을 사용하는 것보다 낮은 수준이지만, 완벽함을 위해 솔루션을 제공합니다.

여기서의 아이디어는 템플릿에 항목 목록을 전달하고 템플릿이 쉼표를 :ttag:〉for〉 루프에 출력하도록 하는 것입니다.

다음은 위와 동일한 CSV 파일을 생성하는 예입니다.

from django.http import HttpResponse
from django.template import loader

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    # The data is hard-coded here, but you could load it from a database or
    # some other source.
    csv_data = (
        ('First row', 'Foo', 'Bar', 'Baz'),
        ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
    )

    t = loader.get_template('my_template_name.txt')
    c = {'data': csv_data}
    response.write(t.render(c))
    return response

이 예와 이전 예와의 유일한 차이점은 이 예에서는 CSV 모듈 대신 템플릿 로드를 사용한다는 것입니다. 《content_type type’text/csv》와 같은 나머지 코드는 동일합니다.

그런 다음 〈〉my_template_name〉 템플릿을 생성합니다.txt², 이 템플릿 코드로 다음을 수행합니다.

{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
{% endfor %}

이 짧은 템플릿은 지정된 데이터에 대해 반복되고 각 행에 대해 CSV 줄을 표시합니다. :t filter:〉addslash〉 템플릿 필터를 사용하여 따옴표에 문제가 없도록 합니다.

기타 텍스트 기반 형식입니다.

CSV에 대한 구체적인 내용은 없고 특정 출력 형식만 있습니다. 이러한 기술 중 하나를 사용하여 원하는 텍스트 기반 형식을 출력할 수 있습니다. 유사한 기술을 사용하여 임의 이진 데이터를 생성할 수도 있습니다. 예제는 :doc:〉/howto/output-pdf’를 참조하십시오.

Back to Top