Here is a view I used to download an excel document based off data that I have:
class ExcelDownloadAllView(TemplateView):
def get(self, request, *args, **kwargs):
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="All_of_Projects.xls"'
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('All Projects Data') # this will make a sheet named Users Data
# Sheet header, first row
row_num = 0
font_style = xlwt.XFStyle()
font_style.font.bold = True
columns = ['Username', 'First Name', 'Last Name', 'Email Address', 'Summary']
rows = BugTracker.objects.all().values_list('project_number','assignee','priority','status','summary',)
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], font_style) # at 0 row 0 column
# Sheet body, remaining rows
font_style = xlwt.XFStyle()
for row in rows:
row_num = 1
for col_num in range(len(row)):
ws.write(row_num, col_num, row[col_num], font_style)
wb.save(response)
return response
It works fine, but now I want to create another CBV with a different "row=" filter. What is the best way to do this using DRY principles?
I tried something like. But the rows variable will get overwritten by the previous class.
class ExcelDownloadOpenView(ExcelDownloadAllView):
def get(self, request, *args, **kwargs):
rows = BugTracker.objects.all().values_list('project_number','assignee', 'priority')
return super().get(request, *args, **kwargs)
Any suggestions without copying the entire method and replacing the rows variable?
CodePudding user response:
Write a function to create a file and attach it to a response and have this function in an outer file to clean up your code. For instance, lets assume a module (app) called core
:
utils.py
import xlwt
from django.http import HttpResponse
def create_sheet_response(columns, rows, filename):
response = HttpResponse(headers={
'Content-Type': 'application/vnd.ms-excel',
'Content-Disposition': f'attachment; filename={filename}',
})
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('All Projects Data')
row_num = 0
font_style = xlwt.XFStyle()
font_style.font.bold = True
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], font_style)
font_style = xlwt.XFStyle()
for row in rows:
row_num = 1
for col_num in range(len(row)):
ws.write(row_num, col_num, row[col_num], font_style)
wb.save(response)
return response
views.py:
from core.models import BugTracker
from core.utils import create_sheet_response
from django.views.generic import TemplateView
class ExcelDownloadAllView(TemplateView):
def get(self, request, *args, **kwargs):
filename = 'All_of_Projects.xls'
columns = ['Username', 'First Name', 'Last Name', 'Email Address', 'Summary']
fields = 'project_number','assignee','priority','status','summary'
rows = BugTracker.objects.all().values_list(*fields)
return create_sheet_response(columns, rows, filename)
class ExcelDownloadOpenView(TemplateView):
def get(self, request, *args, **kwargs):
filename = 'NotAll_of_Projects.xls'
columns = ['Username', 'First Name', 'Last Name']
fields = 'project_number','assignee', 'priority'
rows = BugTracker.objects.all().values_list(*fields)
return create_sheet_response(columns, rows, filename)