django - 如何优化我的代码和数据库访问?
问题描述
我正在创建一个中小企业预算应用程序,我需要在其中管理大量数据(巨大的产品列表、资产负债表等)。
我希望有一个高效和优化的代码,尊重 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()
我想根据注册数据获得一个月度表格,其中汇总了quantita
每个单曲“”的所有“”金额conto
。
解决方案
我不是 Django orm 专家,但我会尽力提供我的答案
contos = Conto.objects.prefetch_related('materiale_set').annotate(totale=Sum('materiale__quantita'))
现在,如果您只想要 2020 年 1 月/2020 年的 Contos,只需
january_contos = contos.filter(materiale__date__year=2020, materiale__date__month=1)
我认为这样你就不会遍历每条Materiale
记录,而只是遍历你需要的月数,让 sql 查询求和而不是 python 代码。预取在这里很重要,否则您将执行大量子查询。
推荐阅读
- javascript - h 没有定义是什么意思?
- java - PostUpdate 挂钩不起作用,同时进行批量更新
- python - 如何找出 Windows 上 FTDI 适配器背后的仪器?
- php - 将错误记录到数据库的 Slim 框架
- c - 循环通过 2D Char Array、Wordsearch 时出现分段错误
- java - 三元运算符返回值
- python - 新文本文档与现有文档列表的余弦相似度
- django - Djongo 使用 ArrayField 在 makemigrations 上引发应用程序无加载错误
- php - 如何解决 Laravel 查询中的空返回?
- gcloud - 当我想部署更新时,Gcloud 目标 URL 意外更改