Исходные данные:
- Джанго проект, база данных
- Есть сложный запрос, с большим количеством данных. Часто запрос моно описать моделями, чтобы усложнить задачу, будем писать сырой запрос mysql
- Необходимо надежно выгрузить в CSV. Может даже миллионы строк
- первой строкой в выгрузке будет хедер с названием столбцов
- кастомный разделитель полей, например точка с запятой
1) views.py
- добавляем необходимые импорты в начале кода
from django.http import StreamingHttpResponse import csv
- файло-подобный объект, который понадобится для добавления строк запроса в выходной CSV
class Echo: def write(self, value): return value
- сам метод выгрузки в csv
def download_csv(filename, rows): pseudo_buffer = Echo() # используем кастомный разделитель полей - точка с запятой, по умолчанию, разделитель - запятая writer = csv.writer(pseudo_buffer, delimiter=';') return StreamingHttpResponse( ( writer.writerow(row) for row in rows ), content_type="text/csv", headers={'Content-Disposition': 'attachment; filename="' + filename + '.csv"'}, )
- и пример его использования:
def download_orders_for_user(request): # например, запрос всех заказов пользователей с айдишниками от 1 до 10000 и суммой больше 10 query = """ SELECT order.number, order.date, order.sum, order.status FROM order LEFT JOIN user ON user.id = order.user_id WHERE user BETWEEN 1 and 10000 AND order.sum > 10 """ with connections["default"].cursor() as cursor: cursor.execute(query) rows = cursor.fetchall() # формируем имя файла filename = 'orders_for_users' # первой строкой у нас будет хедер с названием столбцов header_row = (('Номер', 'Дата', 'Сумма', 'Статус'),) rows = header_row + rows return download_csv(filename, rows)
2) urls.py
Зададим 2 урла:
- для страницы, со ссылкой на выгрузку
- для запроса выгрузки (нажатие на ссылку выгрузки)
… urlpatterns = [ … path('download_page/', views.download_page, name='download_page'), path('download_page/csv/', views.download_orders_for_user, name='download_orders_for_user'), ]
3) создадим темплейт с HTML страничкой
для размещения ссылки скачивания и проверки работы наших скриптов
download_page.html
со следующим содержимым:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Download SCV</title> </head> <body> <div> <h4>Скачать заказы пользователей: </h4> <a id="download" href="csv/">CSV</a> </div> </body> </html>
Это все!
Hello! I know this is kinda off topic however I’d figured I’d ask.
Would you be interested in exchanging links or maybe guest authoring a blog article or vice-versa?
My website discusses a lot of the same topics as yours and
I feel we could greatly benefit from each other. If you happen to be interested feel free to shoot
me an email. I look forward to hearing from you! Great blog by the way!
Howdy! Do you use Twitter? I’d like to follow you if that would
be okay. I’m undoubtedly enjoying your blog and look forward to new posts.
I for all time emailed this webpage post
page to all my friends, for the reason that if like to
read it afterward my contacts will too.