mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
API: Fix N+1 query in gift card list
This commit is contained in:
@@ -24,6 +24,8 @@ from decimal import Decimal
|
|||||||
import django_filters
|
import django_filters
|
||||||
from django.contrib.auth.hashers import make_password
|
from django.contrib.auth.hashers import make_password
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.db.models import OuterRef, Subquery, Sum
|
||||||
|
from django.db.models.functions import Coalesce
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||||
@@ -155,8 +157,13 @@ class GiftCardViewSet(viewsets.ModelViewSet):
|
|||||||
qs = self.request.organizer.accepted_gift_cards
|
qs = self.request.organizer.accepted_gift_cards
|
||||||
else:
|
else:
|
||||||
qs = self.request.organizer.issued_gift_cards.all()
|
qs = self.request.organizer.issued_gift_cards.all()
|
||||||
|
s = GiftCardTransaction.objects.filter(
|
||||||
|
card=OuterRef('pk')
|
||||||
|
).order_by().values('card').annotate(s=Sum('value')).values('s')
|
||||||
return qs.prefetch_related(
|
return qs.prefetch_related(
|
||||||
'issuer'
|
'issuer'
|
||||||
|
).annotate(
|
||||||
|
cached_value=Coalesce(Subquery(s), Decimal('0.00'))
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_serializer_context(self):
|
def get_serializer_context(self):
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ class GiftCard(LoggedModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
if hasattr(self, 'cached_value'):
|
||||||
|
return self.cached_value or Decimal('0.00')
|
||||||
return self.transactions.aggregate(s=Sum('value'))['s'] or Decimal('0.00')
|
return self.transactions.aggregate(s=Sum('value'))['s'] or Decimal('0.00')
|
||||||
|
|
||||||
def accepted_by(self, organizer):
|
def accepted_by(self, organizer):
|
||||||
|
|||||||
Reference in New Issue
Block a user