Optimise down to just the one SQL query for waiting invoices.

Cuts down on all the unnecessary queries and selects everything in one go.
Down from ~6 queries per invoice
This commit is contained in:
Tom Price
2017-03-01 02:42:39 +00:00
parent 4773b43081
commit 7ec1c726a6
2 changed files with 14 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
import cStringIO as StringIO import cStringIO as StringIO
import datetime import datetime
import re import re
from decimal import Decimal
from django.contrib import messages from django.contrib import messages
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
@@ -31,12 +32,13 @@ class InvoiceIndex(generic.ListView):
def get_queryset(self): def get_queryset(self):
query = self.model.objects.annotate( query = self.model.objects.annotate(
cost=Sum(F('event__items__cost') * F('event__items__quantity'), output_field=FloatField()), _sum_total=Sum(F('event__items__cost') * F('event__items__quantity'), output_field=FloatField()),
payment_count=Count('payment'), _payment_count=Count('payment'),
payments=Sum('payment__amount'), _payment_total=Sum('payment__amount'),
).filter( ).filter(
Q(cost__gt=0.0, payment_count=0) | Q(cost__lt=Value('payments'), cost__gt=Value('payments')) Q(_sum_total__gt=0.0, _payment_count=0) |
).select_related('event', 'event__organisation', 'event__person', 'event__venue') Q(_sum_total__lt=Value('_payment_total'), _sum_total__gt=Value('_payment_total'))
).select_related('event', 'event__organisation', 'event__person', 'event__venue', 'event__mic')
return query return query

View File

@@ -1,11 +1,11 @@
import datetime import datetime
import hashlib import hashlib
import pytz
import random import random
import string import string
from collections import Counter from collections import Counter
from decimal import Decimal from decimal import Decimal
import pytz
import reversion import reversion
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
@@ -509,6 +509,8 @@ class Invoice(models.Model):
@property @property
def sum_total(self): def sum_total(self):
if getattr(self, '_sum_total', None):
return Decimal(getattr(self, '_sum_total'))
return self.event.sum_total return self.event.sum_total
@property @property
@@ -517,6 +519,10 @@ class Invoice(models.Model):
@property @property
def payment_total(self): def payment_total(self):
if hasattr(self, '_payment_total') and hasattr(self, '_payment_count'):
if getattr(self, '_payment_count') == 0:
return Decimal(0.00)
return Decimal(getattr(self, '_payment_total', 0.00))
total = self.payment_set.aggregate(total=models.Sum('amount'))['total'] total = self.payment_set.aggregate(total=models.Sum('amount'))['total']
if total: if total:
return total return total