Создание CSV с помощью Django

В этом документе объясняется, как динамически создавать содержимое CSV (значения, разделенные запятыми) с помощью представлений Django. Вы можете использовать для этого либо CSV-библиотеку Django, либо систему шаблонов Django.

Библиотека Python CSV

Python содержит библиотеку CSV csv . Ключом к его использованию с Django является то, что функции создания CSV модуля csv работают с файловыми объектами, а объекты HttpResponse Django являются просто объектами файлового типа.

Вот пример:

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-типом text / csv . Это сообщает браузерам, что документ является файлом CSV, а не файлом HTML. Если вы опустите этот параметр, браузеры, скорее всего, интерпретируют содержимое как HTML, что приведет к появлению загадочного отображения, напоминающего секретный код.
  • Заголовок Content-Disposition ответа также определяется именем файла CSV. Это имя совершенно произвольно, дайте ему любое имя, которое хотите. В частности, он будет использоваться браузерами в диалоговом окне «Сохранить как».
  • Можно подключиться к API создания CSV, передав response в качестве первого параметра csv.writer . Функция csv.writer ожидает объект типа file и HttpResponse очень хорошо выполняет эту роль.
  • Для каждой строки в вашем CSV-файле назовите writer.writerow ее передачей повторяемого объекта .
  • Модуль CSV заботится о кавычках, поэтому вам не нужно беспокоиться об экранировании строк, содержащих кавычки или запятые. Передайте свои необработанные струны, writerow() и он сделает все, что для этого потребуется.

Непрерывная потоковая передача больших файлов CSV

Когда вы имеете дело с представлениями, которые вызывают очень большие отклики, подумайте об использовании ответов StreamingHttpResponse . Например, при непрерывной потоковой передаче файла, создание которого занимает много времени, вы можете избежать потери соединения с балансировщиком нагрузки, которое в противном случае истекло бы, пока сервер генерировал ответ.

В этом примере мы в полной мере используем генераторы 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

Использование системы шаблонов

У вас также есть возможность использовать систему шаблонов Django для создания CSV. Этот метод является более низким уровнем, чем использование модуля Python csv , но эта альтернатива представлена ​​здесь для полноты картины.

Идея состоит в том, чтобы передать список элементов в шаблон, который будет генерировать запятые в цикле 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='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 для каждой строки. Он использует шаблонный фильтр, addslashes чтобы убедиться, что с кавычками не будет проблем.

Другие текстовые форматы

Вы обнаружите, что эти примеры не содержат большого количества конкретного кода в формате CSV, а содержат только определенный выходной формат. Таким образом, вы можете использовать любой из этих методов для создания любого другого текстового формата. Вы также можете использовать аналогичные методы для создания любого двоичного содержимого; см. пример в разделе Создание PDF-файлов с помощью Django .

Copyright ©2020 All rights reserved