Further SQL optimizations

This commit is contained in:
Raphael Michel
2016-11-08 16:58:48 +01:00
parent 4c80ec17bf
commit 37598ed914
8 changed files with 65 additions and 23 deletions

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-11-08 15:42
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0044_auto_20161101_1610'),
]
operations = [
migrations.AlterField(
model_name='cartposition',
name='expires',
field=models.DateTimeField(db_index=True, verbose_name='Expiration date'),
),
migrations.AlterField(
model_name='voucher',
name='redeemed',
field=models.BooleanField(db_index=True, default=False, verbose_name='Redeemed'),
),
migrations.AlterField(
model_name='voucher',
name='valid_until',
field=models.DateTimeField(blank=True, db_index=True, null=True, verbose_name='Valid until'),
),
]

View File

@@ -582,7 +582,7 @@ class Quota(LoggedModel):
Q(redeemed=False) &
Q(Q(valid_until__isnull=True) | Q(valid_until__gte=now_dt)) &
Q(Q(self._position_lookup) | Q(quota=self))
).distinct().count()
).values('id').distinct().count()
def count_in_cart(self, now_dt: datetime=None) -> int:
from pretix.base.models import CartPosition
@@ -595,21 +595,22 @@ class Quota(LoggedModel):
& Q(Q(voucher__valid_until__isnull=True) | Q(voucher__valid_until__gte=now_dt))
) &
self._position_lookup
).distinct().count()
).values('id').distinct().count()
def count_pending_orders(self) -> dict:
from pretix.base.models import Order, OrderPosition
# This query has beeen benchmarked against a Count('id', distinct=True) aggregate and won by a small margin.
return OrderPosition.objects.filter(
self._position_lookup, order__status=Order.STATUS_PENDING,
).distinct().count()
).values('id').distinct().count()
def count_paid_orders(self):
from pretix.base.models import Order, OrderPosition
return OrderPosition.objects.filter(
self._position_lookup, order__status=Order.STATUS_PAID
).distinct().count()
).values('id').distinct().count()
@cached_property
def _position_lookup(self) -> Q:

View File

@@ -515,7 +515,8 @@ class CartPosition(AbstractPosition):
auto_now_add=True
)
expires = models.DateTimeField(
verbose_name=_("Expiration date")
verbose_name=_("Expiration date"),
db_index=True
)
class Meta:

View File

@@ -70,10 +70,11 @@ class Voucher(LoggedModel):
)
redeemed = models.BooleanField(
verbose_name=_("Redeemed"),
default=False
default=False,
db_index=True
)
valid_until = models.DateTimeField(
blank=True, null=True,
blank=True, null=True, db_index=True,
verbose_name=_("Valid until")
)
block_quota = models.BooleanField(

View File

@@ -4,7 +4,6 @@ from typing import Any, Dict
from django import forms
from django.contrib import messages
from django.db.models import Sum
from django.dispatch import receiver
from django.forms import Form
from django.http import HttpRequest
@@ -13,9 +12,10 @@ from django.utils.translation import ugettext_lazy as _
from pretix.base.decimal import round_decimal
from pretix.base.i18n import I18nFormField, I18nTextarea, LazyI18nString
from pretix.base.models import CartPosition, Event, Order, Quota
from pretix.base.models import Event, Order, Quota
from pretix.base.settings import SettingsSandbox
from pretix.base.signals import register_payment_providers
from pretix.presale.views import get_cart_total
class BasePaymentProvider:
@@ -503,9 +503,7 @@ class FreeOrderProvider(BasePaymentProvider):
messages.success(request, _('The order has been marked as refunded.'))
def is_allowed(self, request: HttpRequest) -> bool:
return CartPosition.objects.filter(
cart_id=request.session.session_key, event=request.event
).aggregate(sum=Sum('price'))['sum'] == 0
return get_cart_total(request) == 0
def order_change_allowed(self, order: Order) -> bool:
return False