From 8f223289cfc71eb21324428c3bd7b6dcd6c68e59 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Mon, 1 Mar 2021 16:35:42 +0100 Subject: [PATCH 1/2] agendas: change annotate_queryset queries (#54332) --- chrono/agendas/models.py | 51 ++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index 438a57c..f1f7575 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -34,7 +34,8 @@ from django.contrib.postgres.fields import ArrayField, JSONField from django.core.exceptions import FieldDoesNotExist, ValidationError from django.core.validators import MaxValueValidator, MinValueValidator from django.db import connection, models, transaction -from django.db.models import Case, Count, Max, Q, When +from django.db.models import Count, IntegerField, Max, OuterRef, Q, Subquery, Value +from django.db.models.functions import Coalesce from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist, engines from django.urls import reverse from django.utils import functional @@ -1296,42 +1297,26 @@ class Event(models.Model): @staticmethod def annotate_queryset(qs): - if django.VERSION < (2, 0): - return qs.annotate( - booked_places_count=Count( - Case( - When( - booking__cancellation_datetime__isnull=True, - booking__in_waiting_list=False, - then='booking', - ) - ) - ), - waiting_list_count=Count( - Case( - When( - booking__cancellation_datetime__isnull=True, - booking__in_waiting_list=True, - then='booking', - ) - ) - ), - ) - else: - return qs.annotate( - booked_places_count=Count( - 'booking', - filter=Q(booking__cancellation_datetime__isnull=True, booking__in_waiting_list=False), - ), - waiting_list_count=Count( - 'booking', - filter=Q(booking__cancellation_datetime__isnull=True, booking__in_waiting_list=True), - ), - ) + not_cancelled_bookings = Booking.objects.filter( + cancellation_datetime__isnull=True, event=OuterRef('pk') + ) + + bookings = not_cancelled_bookings.filter(in_waiting_list=False).order_by().values('event') + count_bookings = bookings.annotate(count=Count('event')).values('count') + + waiting_list_bookings = not_cancelled_bookings.filter(in_waiting_list=True).order_by().values('event') + count_waiting_list = waiting_list_bookings.annotate(count=Count('event')).values('count') + + return qs.annotate( + booked_places_count=Coalesce(Subquery(count_bookings, output_field=IntegerField()), Value(0)), + waiting_list_count=Coalesce(Subquery(count_waiting_list, output_field=IntegerField()), Value(0)), + ) @staticmethod def annotate_queryset_for_user(qs, excluded_user_external_id): if django.VERSION < (2, 0): + from django.db.models import Case, When + return qs.annotate( user_places_count=Count( Case( -- 2.20.1