From 57d5b3f131077ac6e73539acb124d1f815a5713e Mon Sep 17 00:00:00 2001 From: "Casper V. Kristensen" Date: Wed, 8 Jan 2020 20:39:29 +0100 Subject: [PATCH] Fix average attendance annotation returning None for users that doesn't have any RaidResponses for past raids yet. This occurs because we don't filter users on weather or not they even have RaidResponses for past raids, but only do the filtering on the Avg function. This is correct behaviour, as we want to show *all* users in the attendance matrix. We therefore introduce the 'Coalesce' function to default to an average attendance of 0. --- drakul/users/views.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drakul/users/views.py b/drakul/users/views.py index 2c5336f..a9c128c 100644 --- a/drakul/users/views.py +++ b/drakul/users/views.py @@ -1,6 +1,7 @@ from contextlib import suppress -from django.db.models import Avg, Q +from django.db.models import Avg, Q, Value +from django.db.models.functions import Coalesce from django.utils import timezone from django.views.generic import TemplateView @@ -17,12 +18,15 @@ class AttendanceView(TemplateView): .filter(is_active=True) \ .select_related("main") \ .annotate( - avg_attendance=Avg( - "characters__raid_responses__attendance", - filter=Q( - characters__raid_responses__raid__date__lte=timezone.now(), # only count past raids - characters__raid_responses__raid__is_optional=False - ) + avg_attendance=Coalesce( + Avg( + "characters__raid_responses__attendance", + filter=Q( + characters__raid_responses__raid__date__lte=timezone.now(), # only count past raids + characters__raid_responses__raid__is_optional=False + ) + ), + Value(0) # default to 0 if user doesn't have any responses for past raids yet ) ).order_by("main__klass", "-avg_attendance", "main__name")