如何避免在循环中重复查询以获取数据

时间:2019-07-10 12:10:41

标签: django python-2.7

我正在以字典格式列表发送网站详细信息。我们从其他表格中提取某些字段(三种类型的付款,其付款状态不同)。 现在,对于循环的每次迭代,将执行三个查询。

我在下面提到了每次迭代都会执行的行

在下面的代码中,我试图获取所有主要付款金额并将其总和。 另外,还有付款的一些状态,例如预付款,已批准付款,已完成付款。

main_payment_raised = sum(mainPaymentVendor.objects.filter(systemId=site['systemId'],approvalStatus='Waiting').values_list('quotation',flat=True))
main_payment_approved = sum(mainPaymentVendor.objects.filter(systemId=site['systemId'],approvalStatus='Approved',paymentStatus='Waiting').values_list('quotation',flat=True))
main_payment_paid = sum(mainPaymentVendor.objects.filter(systemId=site['systemId'],paymentStatus='Confirm',approvalStatus='Approved').values_list('quotation',flat=True))


partial_payment_raised = sum(partialPaymentVendor.objects.filter(systemId=site['systemId'],approvalStatus='Waiting').values_list('amount',flat=True))
partial_payment_approved = sum(partialPaymentVendor.objects.filter(systemId=site['systemId'],approvalStatus='Approved',paymentStatus='Waiting').values_list('amount',flat=True))
partial_payment_paid = sum(partialPaymentVendor.objects.filter(systemId=site['systemId'],paymentStatus='Confirm',approvalStatus='Approved').values_list('amount',flat=True))
extra_payment_raised = sum(extraPaymentVendor.objects.filter(systemId=site['systemId'],approvalStatus='Waiting').values_list('amount',flat=True))
extra_payment_approved = sum(extraPaymentVendor.objects.filter(systemId=site['systemId'],approvalStatus='Approved',paymentStatus='Waiting').values_list('amount',flat=True))
extra_payment_paid = sum(extraPaymentVendor.objects.filter(systemId=site['systemId'],paymentStatus='Confirm',approvalStatus='Approved').values_list('amount',flat=True))

整个功能正在消耗更多时间。 是否有任何优化的方法可以使结果的复杂性降到最低

P.S。我正在使用Django 1.11和Python 2.7

1 个答案:

答案 0 :(得分:1)

一种方法是使用conditional annotation。例如:

from django.db.modles import Sum, Case, IntegerField

mainPaymentVendor.objects.filter(
    systemId=site['systemId']
).annotate(main_payment_raised=Sum(
    Case(
        When(approvalStatus="Waiting", then=1),
        output_field=IntegerField(),
    ))
).annotate(main_payment_approved=Sum(
    Case(
        When(approvalStatus="Approved", then=1),
        output_field=IntegerField(),
    ))
).annotate(main_payment_paid=Sum(
    Case(
        When(approvalStatus="Confirm", then=1),
        output_field=IntegerField(),
    ))
).values('main_payment_raised', 'main_payment_approved', 'main_payment_paid')