【问题标题】:How to optimize my code and the database access?如何优化我的代码和数据库访问?
【发布时间】:2020-05-07 07:10:16
【问题描述】:

我正在创建一个中小企业预算应用程序,我需要在其中管理大量数据(庞大的产品列表、资产负债表等)。

我希望有一个高效和优化的代码,尊重 DRY 原则,并减少对数据库的查询集。

在我的views.py中的广告示例这段代码是否高效且优化?

def conto_economico(request):
    # Creazione tabella materie prime, sussidiarie, di consumo e merci
    defaults = list(0 for m in range(12))
    elements = dict()
    for conto_id, year, month, totale in(Materiale.objects.values_list('conto__nome', 'data__year', 'data__month').annotate(totale=ExpressionWrapper(Sum(F('quantita') * F('prezzo')),
        output_field=FloatField())).values_list('conto__nome', 'data__year', 'data__month', 'totale').order_by("conto_id")) :
        if conto_id not in elements.keys():
            elements[conto_id]=list(defaults)
        index=month-1
        elements[conto_id][index]=totale

    total_elements={'Per materie prime, sussidiarie, di consumo e di merci': [sum(t) for t in zip(*elements.values())],}

我将这段代码用于很多模型来创建我的表格,但我认为这效率不高。

这是我的模型:

class MaterialeManager(models.Manager):
    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).annotate(
            iva_amount=ExpressionWrapper(F('quantita')*F('prezzo')*F('iva'),output_field=FloatField())
        ).annotate(totale_netto=ExpressionWrapper(F('quantita')*F('prezzo'),output_field=FloatField()))


class Materiale(models.Model):
    conto = models.ForeignKey(Conto, on_delete=models.CASCADE, null=True)
    tipologia = models.ForeignKey(Tipologia, on_delete=models.CASCADE, null=True)
    sottocategoria = models.ForeignKey(Sottocategoria, on_delete=models.CASCADE, null=True)
    um = models.CharField('U.M.', max_length=30, unique=False, blank=True, default="")
    quantita=models.DecimalField('Quantità',max_digits=5, decimal_places=2, default="")
    prezzo=models.DecimalField('Prezzo di acquisto', max_digits=5, decimal_places=2, default="")
    iva=models.DecimalField('I.V.A. in %', max_digits=5, decimal_places=2, default="0.22")
    data=models.DateField('Data di acquisto', default="GG/MM/YYYY")
    giorni_dilazione=models.IntegerField('Giorni dilazione pagamento', default="")
    objects=MaterialeManager()

我想根据注册数据获得一个月度表格,其中包含每个“conto”的所有“quantita”金额。

【问题讨论】:

  • 很难想象你想用这段代码实现什么。也许你可以分享模型和你从这段代码中得到的结果的可视化表示。
  • 我已经添加了模型以及我想用它做什么

标签: django django-models django-rest-framework django-forms django-views


【解决方案1】:

我不是 Django orm 专家,但我会尽力提供我的答案

contos = Conto.objects.prefetch_related('materiale_set').annotate(totale=Sum('materiale__quantita'))

现在,如果您只想要 2020 年 1 月的 Contos,只需

january_contos = contos.filter(materiale__date__year=2020, materiale__date__month=1)

我认为这样您就不会遍历每条Materiale 记录,而是遍历您需要的月数,让 sql 查询而不是 python 代码求和。预取在这里很重要,否则您将执行大量子查询。

【讨论】:

    猜你喜欢
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2017-05-20
    • 2013-06-29
    • 1970-01-01
    • 2015-11-23
    • 2020-10-08
    相关资源
    最近更新 更多