Removing a personalized class inside the view.py – Django

here is my view.py. Despite the code is a little bit long, I’d like to remove the class Ibm() from inside the else element to a new file called Ibm_class.py. I tried to do that but I couldn’t find any way!

def index(request):
if 'GET' == request.method:
return render(request, 'auditoria_app/index.html')
else:
class Ibm(object):
def __init__(self, i):
self.numeroIbm = inputsCombo[get_column_letter(i) + str(10)].value
self.nome = inputsCombo[get_column_letter(i) + str(11)].value
self.cidade = inputsCombo[get_column_letter(i) + str(12)].value
self.uf = inputsCombo[get_column_letter(i) + str(13)].value
self.anosProjeto = inputsCombo[get_column_letter(i) + str(16)].value
self.anosAlternativa = inputsDNCombo[get_column_letter(i) + str(14)].value
if self.anosAlternativa is None:
self.anosAlternativa = 0
self.tipoInvestimento = inputsCombo[get_column_letter(i) + str(21)].value
self.tipoProposta = inputsCombo[get_column_letter(i) + str(24)].value
self.inicioVigencia = inputsCombo[get_column_letter(i) + str(34)].value
self.prazoContrato = inputsCombo[get_column_letter(i) + str(38)].value
# gas station variables
self.faixaMargem = inputsCombo[get_column_letter(i) + str(19)].value
self.rebateTotalCI = 0
self.rebateTotalCB = 0
self.unitariaCI = 0
self.volumeMensalCI = inputsCombo[get_column_letter(i) + str(60)].value
self.volumeMensalCB = inputsDNCombo[get_column_letter(i) + str(32)].value
self.margemCurva = inputsCombo[get_column_letter(i) + str(67)].value * 1000
self.margemCI = []
self.margemCB = []
self.volume12m = 0
self.margem12m = 0
self.curvaPostoCI = []
self.curvaPostoCB = []
self.rebateCI = []
self.rebateCB = []
self.faixaReal = ''
self.volumeTotalCI = inputsCombo[get_column_letter(i) + str(151)].value
self.volumeTotalCB = inputsDNCombo[get_column_letter(i) + str(121)].value
# SELECT store variables
self.feeIsencao = inputsCombo[get_column_letter(i) + str(220)].value
self.feeFaturamento = inputsCombo[get_column_letter(i) + str(222)].value
self.feeReal = inputsCombo[get_column_letter(i) + str(224)].value
self.faturamento = inputsCombo[get_column_letter(i) + str(173)].value
self.pvl = inputsCombo[get_column_letter(i) + str(184)].value
self.feeLoja = inputsCombo[get_column_letter(i) + str(174)].value
self.cashback = []
# credit variables
self.prazoMogasCI1 = inputsCombo[get_column_letter(i) + str(159)].value
self.prazoMogasCI2 = inputsCombo[get_column_letter(i) + str(160)].value
self.prazoMogasCI3 = inputsCombo[get_column_letter(i) + str(161)].value
self.prazoMogasCB1 = inputsDNCombo[get_column_letter(i) + str(151)].value
self.prazoMogasCB2 = inputsDNCombo[get_column_letter(i) + str(152)].value
self.prazoMogasCB3 = inputsDNCombo[get_column_letter(i) + str(153)].value
# economics IBM
self.unitariaIBM = arredonda(outputCombo[get_column_letter(i - 1) + str(42)].value)
self.hsIBM = arredonda(outputCombo[get_column_letter(i - 1) + str(36)].value)
self.cmIBM = percentual(outputCombo[get_column_letter(i - 1) + str(39)].value)
self.tirIBM = percentual(outputCombo[get_column_letter(i - 1) + str(54)].value)
self.npvIBM = arredonda(outputCombo[get_column_letter(i - 1) + str(55)].value)
# if self.tipoInvestimento != 'Loja':
for k in range(0, self.anosProjeto):
margemCI = inputsCombo[get_column_letter(i) + str(109 + k)].value
if margemCI is None or margemCI == '':
margemCI = 0
self.margemCI.append(arredonda(margemCI * 1000))
curvaPostoCI = inputsCombo[get_column_letter(i) + str(130 + k)].value
if curvaPostoCI is None or 0:
curvaPostoCI = 1
self.curvaPostoCI.append(arredonda(curvaPostoCI * 100))
rebateCI = inputsCombo[get_column_letter(i) + str(305 + k)].value
if rebateCI is None:
rebateCI = 0
self.rebateCI.append(rebateCI * 1000)
cashback = inputsCombo[get_column_letter(i) + str(485 + k)].value
if cashback is None:
cashback = 0
else:
cashback = cashback / self.faturamento
self.cashback.append(cashback)
for y in range(0, self.anosAlternativa):
margemCB = inputsDNCombo[get_column_letter(i) + str(79 + y)].value
if margemCB is None or margemCB == '':
margemCB = 0
self.margemCB.append(arredonda(margemCB * 1000))
curvaPostoCB = inputsDNCombo[get_column_letter(i) + str(100 + y)].value
if curvaPostoCB is None or 0:
curvaPostoCB = 1
self.curvaPostoCB.append(arredonda(curvaPostoCB * 100))
rebateCB = inputsDNCombo[get_column_letter(i) + str(204 + y)].value
if rebateCB is None:
rebateCB = 0
self.rebateCB.append(rebateCB * 1000)
# Selecionando os dados da Loja Select
# if self.tipoInvestimento == 'Loja':
self.curvaLojaCI = []
self.curvaLojaCB = []
for k in range(0, self.anosProjeto):
curvaLojaCI = inputsCombo[get_column_letter(i) + str(198 + k)].value
if curvaLojaCI is None or 0:
curvaLojaCI = 1
self.curvaLojaCI.append(curvaLojaCI)
for k in range(0, self.anosAlternativa):
curvaLojaCB = inputsDNCombo[get_column_letter(i) + str(123 + k)].value
if curvaLojaCB is None or 0:
curvaLojaCB = 1
self.curvaLojaCB.append(curvaLojaCB)
self.fpCI = inputsCombo[get_column_letter(i) + str(283)].value
if self.fpCI is None:
self.fpCI = 0
self.rviCI = inputsCombo[get_column_letter(i) + str(285)].value
if self.rviCI is None:
self.rviCI = 0
self.fpCB = inputsDNCombo[get_column_letter(i) + str(201)].value
if self.fpCB is None:
self.fpCB = 0
self.rviCB = inputsDNCombo[get_column_letter(i) + str(202)].value
if self.rviCB is None:
self.rviCB = 0
# initializing gas station functions
self.get_volume()
self.rebate_total_CI()
self.rebate_total_CB()
# self.unitaria_CI()
self.check_faixa()
def get_volume(self):
if self.tipoInvestimento != 'Loja':
for j in range(2, sigma.max_row + 1):
if self.numeroIbm == sigma['A' + str(j)].value:
self.margem12m = sigma['D' + str(j)].value
self.volume12m = sigma['E' + str(j)].value
def check_faixa(self):
if self.tipoInvestimento != 'Loja':
if self.faixaMargem[0] == 'R':
pass
else:
for row in range(5, faixas.max_row + 1):
cidade = faixas['C' + str(row)].value
if cidade == unidecode.unidecode(self.cidade.upper() + '/' + self.uf.upper()):
self.faixaReal = faixas['D' + str(row)].value
if self.faixaReal == '':
self.faixaReal = 'n/a'
def rebate_total_CI(self):
if self.tipoInvestimento != 'Loja':
rebateTotalCI = 0
for k in range(0, self.anosProjeto):
rebateTotalCI += self.volumeMensalCI * 12 * self.curvaPostoCI[k] * self.rebateCI[k]
self.rebateTotalCI = arredonda(rebateTotalCI / 1000)
def rebate_total_CB(self):
if self.tipoInvestimento != 'Loja':
rebateTotalCB = 0
for k in range(0, self.anosAlternativa):
rebateTotalCB += self.volumeMensalCB * 12 * self.curvaPostoCB[k] * self.rebateCB[k]
self.rebateTotalCB = arredonda(rebateTotalCB / 1000)
# UNIT might be extracted from 'OutPut COMBO'
# def unitaria_CI(self):
#     self.unitariaCI = (self.rebateTotalCI + self.fpCI + self.rviCI)*10/self.volumeTotalCI
def check_volume_mensal(self):
return self.volumeMensalCI - self.volumeMensalCB
def check_volume_total(self):
return self.volumeTotalCI - self.volumeTotalCB
def check_volumeCB_SIC(self):
return self.volumeMensalCB
excel_file = request.FILES["excel_file"]
wb = openpyxl.load_workbook(excel_file, data_only=True)
inputsCombo = wb['Inputs COMBO']
inputsDNCombo = wb['Inputs DN COMBO']
outputCombo = wb['OutPut COMBO']
faixas = wb['Faixas']
wb2 = openpyxl.load_workbook('media/sigma.xlsx', data_only=True)
sigma = wb2['Planilha1']
wb3 = openpyxl.load_workbook('media/performance.xlsx', data_only=True)
sic = wb3['Performance']
wb4 = openpyxl.load_workbook('media/ultimoContrato.xlsm', data_only=True)
ultimoContrato = wb4['Base']
numeroIbms = inputsCombo['F5'].value
ibms = []
for i in range(8, 8 + numeroIbms):
ibm = Ibm(i)
ibms.append(ibm)
return render(request, 'auditoria_app/index.html', {'ibms': ibms})

-> wb: file is loaded from a upload

-> wb2, wb3, wb4: files are stored inside the media folder

I tried to copy/paste this class and then import it to the view.py file but the excel_file variable must be inside the view and is still needed inside the Ibm_class.py. Any suggestion, pls?

Thank you!

Answer

Use dependency injection on your class instead of relying on local/global scope variables. Here, instead of directly using inputsCombo, inputsDNCombo, outputCombo, faixas, and sigma variables within your class, just pass them to the Ibm constructor as class attributes.

views.py

...
from my_app.ibm import Ibm  # Or wherever you would put that class
...
def index(request):
...
else:
excel_file = request.FILES["excel_file"]
wb = openpyxl.load_workbook(excel_file, data_only=True)
inputsCombo = wb['Inputs COMBO']
inputsDNCombo = wb['Inputs DN COMBO']
outputCombo = wb['OutPut COMBO']
faixas = wb['Faixas']
wb2 = openpyxl.load_workbook('media/sigma.xlsx', data_only=True)
sigma = wb2['Planilha1']
...
for i in range(8, 8 + numeroIbms):
# Pass the dependencies to the constructor of Ibm class
ibm = Ibm(i, inputsCombo, inputsDNCombo, outputCombo, faixas, sigma)
...
...

ibm.py

class Ibm(object):
# Accept the injected parameters to Ibm class
def __init__(self, i, inputsCombo, inputsDNCombo, outputCombo, faixas, sigma):
self.numeroIbm = inputsCombo[get_column_letter(i) + str(10)].value
self.anosAlternativa = inputsDNCombo[get_column_letter(i) + str(14)].value
self.unitariaIBM = arredonda(outputCombo[get_column_letter(i - 1) + str(42)].value)
# For the arguments that will be used by your other functions e.g. check_faixa, define them as class attributes here
self.faixas = faixas
self.sigma = sigma
def get_volume(self):
if self.tipoInvestimento != 'Loja':
for j in range(2, self.sigma.max_row + 1):  # Append "self." to the usage of "sigma" to refer to the class attribute that was set in __init__
if self.numeroIbm == self.sigma['A' + str(j)].value:
self.margem12m = self.sigma['D' + str(j)].value
self.volume12m = self.sigma['E' + str(j)].value
def check_faixa(self):
if self.tipoInvestimento != 'Loja':
if self.faixaMargem[0] == 'R':
pass
else:
for row in range(5, self.faixas.max_row + 1):    # Append "self." to the usage of "faixas" to refer to the class attribute that was set in __init__
cidade = self.faixas['C' + str(row)].value
if cidade == unidecode.unidecode(self.cidade.upper() + '/' + self.uf.upper()):
self.faixaReal = self.faixas['D' + str(row)].value
if self.faixaReal == '':
self.faixaReal = 'n/a'