Django скачать файл с помощью CBV

Как использовать представления на основе классов, например TemplateView, для отображения шаблона Django со ссылками на скачивание? Щелчок по ссылке должен начать загрузку выбранного файла. Я уже знаю, как это сделать с помощью Function Based Views.

Также - является ли хорошей идеей помещать filename slug в качестве параметра URL (filename) для GET запросов или я должен использовать другой метод?

Не так уж плохо создавать slug с именем файла, если вы соблюдаете бизнес-логику и вопросы безопасности

В основном вы хотите отправить запрос в CBV и получить ответ, содержащий ваш CSV.

Предположу, что вы хотите использовать тот же CBV, который вы уже используете, например, для вашего TemplateView. Для этого я бы настроил метод def post(self, request) на CBV для обработки вашего конкретного запроса, что-то вроде:

class MyTemplateView(TemplateView):

    def post(self, request, *args, **kwargs):
        request_type = request.POST.get("type", [])
        
        # Check whether the request type indicates we should generate
        # a CSV
        if "generate_csv" in request_type:
            return self.generate_csv()

        return super(MyTemplateView, self).post(*args, **kwarfs)

    def generate_csv(self):
        response = HttpResponse(content_type="text/csv")
        response[
            "Content-Disposition"
        ] = 'attachment; filename="name_of_csv_download_{}.csv"'.format(
            time.strftime("%d/%m/%Y")
        )

        writer = csv.writer(response)
        writer.writerow(
            [
                "Heading 1",
                "Heading 2",
                "Heading 3",
                etc
            ]
        )

        data = ...get data you want to write to csv...

        for row in data:
            writer.writerow(
                [
                    row.id,
                    row.property1,
                    row.property2,
                    etc
                ]
            )

        return response

Итак, ключевым моментом здесь является установка правильного content_type в ответе, наряду с заголовком Content-Disposition. По сути, это не отличается от того, как мы делаем вещи с представлениями на основе функций, как подробно описано здесь, и вы можете применить точно такую же логику к вашему def get(self, request), используя параметры запроса, а не параметры сообщения, чтобы достичь точно такого же результата.

Вернуться на верх