You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django如何将view.py内自定义Ibm类迁移至独立文件

解决方案

核心思路是将类依赖的视图局部工作表对象,作为构造参数传入独立类即可完成抽离,具体实现如下:

步骤1:编写 Ibm_class.py 文件

将原类代码复制到该文件中,修改构造方法接收依赖的工作表对象,同时导入需要的工具依赖:

from openpyxl.utils import get_column_letter
import unidecode
# 根据你项目的实际路径,导入自定义工具函数
from .utils import arredonda, percentual

class Ibm(object):
    # 新增依赖参数,顺序可自行调整
    def __init__(self, i, inputsCombo, inputsDNCombo, outputCombo, faixas, sigma):
        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

如果arredonda、percentual是你原写在view.py里的自定义函数,也可以移到公共工具文件中再导入,或者作为额外参数传入即可。

步骤2:修改原 view.py 代码

  1. 顶部导入独立的Ibm类:
# 路径根据你的项目结构调整,同目录下可以这么写
from .Ibm_class import Ibm
  1. 保留原视图中加载所有Excel文件的代码不变,实例化Ibm时传入依赖的工作表对象即可:
def index(request):
    if 'GET' == request.method:
        return render(request, 'auditoria_app/index.html')
    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']

        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, inputsCombo, inputsDNCombo, outputCombo, faixas, sigma)
            ibms.append(ibm)

        return render(request, 'auditoria_app/index.html', {'ibms': ibms})

可选优化

存放在media目录下的固定Excel文件(sigma.xlsx、performance.xlsx等)不需要每次请求都重复加载,可以用Django的缓存机制将读取后的workbook对象缓存起来,减少磁盘IO提升接口响应速度。


内容的提问来源于stack exchange,提问作者Felipe Dourado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 17:39:03