Как избежать повторения запроса в цикле для извлечения данных - PullRequest
0 голосов
/ 10 июля 2019

Я отправляю информацию о сайтах в виде списка в формате словаря.Где некоторые поля (три типа платежей с разными статусами платежей) мы выбираем из других таблиц.Прямо сейчас для каждой итерации цикла выполняются три запроса.

Я упомянул ниже строки, которые выполняются для каждой итерации

В приведенном ниже коде я пытаюсь получить всю основную сумму платежа и суммировать эту сумму.Также есть некоторые статусы платежа, такие как: платеж выполнен, платеж утвержден, платеж завершен.

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))

Вся эта функциональность требует больше времени.Есть ли оптимизированный способ получить результат с минимальной сложностью

PS Я использую Django 1.11 и Python 2.7

1 Ответ

1 голос
/ 10 июля 2019

Одним из способов является использование 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...