'Django - Create downloadable Excel file using Pandas & Class Based View

I'm relatively new to Django and have been looking for a way to export my DataFrame to Excel using Pandas and CBV. I have found this code:

from django.http import HttpResponse

def my_view(request):
    # your pandas code here to grab the data
    response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename="foo.xls"'
    return response

It's perfect for a FBV model but how can I manage to tweak it to pass it into get_context_data? Here's my code:

class ResultView(TemplateView):
    template_name = 'tool/result.html'

    # def get(self, request, *args, **kwargs):

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user
        context['result'] = self.request.session['result']
        result = context['result']

        # Transformation into DF
        df = pd.DataFrame(result) #to be transformed into Excel File
        # pprint(df)

        # Count number of rows
        nb_rows = df[df.columns[0]].count()
        context['nb_rows'] = nb_rows

        # Count number of rows which are errored
        nb_errors = np.sum(df['IsSimilar'] == True)
        context['nb_errors'] = nb_errors

        # Sum all rows
        total_amount = df['Montant_HT'].sum()
        context['total_amount'] = total_amount

        # Sum all rows which are errored
        rows_errors_sum = df.loc[df['IsSimilar'] == True, ['Result']].sum().values
        rows_errors_sum = str(rows_errors_sum).replace('[', '').replace(']', '')
        rows_errors_sum = float(rows_errors_sum)
        context['rows_errors_sum'] = rows_errors_sum


        return context

I can't manage to make the request within my class ResultView. Could you help me with that?



Solution 1:[1]

I finally managed to do it by creating another view named DownloadView and by overriding the get method. Here's the code:


class ResultView(TemplateView):
    template_name = 'tool/result.html'



    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user
        context['result'] = self.request.session['result']
        result = context['result']

        # Transformation into DF
        df = pd.DataFrame(result)
        # pprint(df)

        # Count number of rows
        nb_rows = df[df.columns[0]].count()
        context['nb_rows'] = nb_rows

        # Count number of rows which are errored
        nb_errors = np.sum(df['IsSimilar'] == True)
        context['nb_errors'] = nb_errors

        # Sum all rows
        total_amount = df['Montant_HT'].sum()
        context['total_amount'] = total_amount

        # Sum all rows which are errored
        rows_errors_sum = df.loc[df['IsSimilar'] == True, ['Result']].sum().values
        rows_errors_sum = str(rows_errors_sum).replace('[', '').replace(']', '')
        rows_errors_sum = float(rows_errors_sum)
        context['rows_errors_sum'] = rows_errors_sum

        return context

class DownloadView(TemplateView):
    template_name = 'tool/download.html'

    def get(self, request, *args, **kwargs):
        content = self.request.session['result']
        df = pd.DataFrame(content)

        with BytesIO() as b:
            writer = pd.ExcelWriter(b, engine='xlsxwriter')
            df.to_excel(writer, sheet_name='Sheet1', index=False)
            writer.save()
            filename = 'Rapport'
            content_type = 'application/vnd.ms-excel'
            response = HttpResponse(b.getvalue(), content_type=content_type)
            response['Content-Disposition'] = 'attachment; filename="' + filename + '.xlsx"'
            return response


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Vincent