Repository: ephios-dev/ephios

Issue:
Consider removing event_signup_state_counts filter
With #846 we introduced counting participation states using the database, which might have made the filter `event_signup_state_counts` used in `event_list.html` obsolete. We should try to remove the filter and use the database-annotations instead. Beware though that currently, the annotation is only computed if the filter form is valid and needs them.
Consider removing event_signup_state_counts filter
With #846 we introduced counting participation states using the database, which might have made the filter `event_signup_state_counts` used in `event_list.html` obsolete. We should try to remove the filter and use the database-annotations instead. Beware though that currently, the annotation is only computed if the filter form is valid and needs them.


Discussion:

Resolving patch:
diff --git a/ephios/core/templatetags/event_extras.py b/ephios/core/templatetags/event_extras.py
--- a/ephios/core/templatetags/event_extras.py
+++ b/ephios/core/templatetags/event_extras.py
@@ -8,7 +8,7 @@
 from django.utils.html import format_html
 from django.utils.safestring import mark_safe
 
-from ephios.core.models import AbstractParticipation, EventType, LocalParticipation, UserProfile
+from ephios.core.models import AbstractParticipation, EventType, UserProfile
 from ephios.core.signals import (
     event_info,
     homepage_info,
@@ -101,18 +101,17 @@ def confirmed_participations(user: UserProfile):
     )
 
 
-@register.filter(name="event_signup_state_counts")
-def event_signup_state_counts(event, user):
+@register.filter(name="event_list_signup_state_counts")
+def event_list_signup_state_counts(event):
     """
-    Return a counter counting states for a users participations for shifts of an event.
-    Uses None as key for no participation info.
+    Using the annotations on the event queryset in the event list view,
+    return a counter counting states for a users participations for shifts of an event.
     """
+    # the counter is nice because we can loop over it in the template and only get non-zero count states
     counter = collections.Counter()
-    for shift in event.shifts.all():
-        for participation in shift.participations.all():
-            if isinstance(participation, LocalParticipation) and participation.user_id == user.id:
-                counter[participation.state] += 1
-                break
+    for state in AbstractParticipation.States:
+        if count := getattr(event, f"state_{state}_count", 0):
+            counter[state] = count
     return counter
 
 
diff --git a/ephios/core/views/event.py b/ephios/core/views/event.py
--- a/ephios/core/views/event.py
+++ b/ephios/core/views/event.py
@@ -107,16 +107,6 @@ def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields["date"].initial = timezone.now().date()
 
-    def clean_date(self):
-        if not self.cleaned_data["date"]:
-            return timezone.now().date()
-        return self.cleaned_data["date"]
-
-    def clean_direction(self):
-        if not self.cleaned_data["direction"]:
-            return "from"
-        return self.cleaned_data["direction"]
-
     def filter_events(self, qs: QuerySet[Event]):
         fdata = self.cleaned_data
 
@@ -139,7 +129,6 @@ def filter_events(self, qs: QuerySet[Event]):
             )
 
         if state_filter := fdata.get("state"):
-            qs = self._annotate_event_participation_states(qs)
             qs = {
                 "confirmed": qs.filter(
                     **{f"state_{AbstractParticipation.States.CONFIRMED}_count__gt": 0}
@@ -195,28 +184,6 @@ def filter_shifts(self, qs: QuerySet[Shift]):
 
         return qs
 
-    def _annotate_event_participation_states(self, qs):
-        qs = qs.annotate(
-            pending_disposition_count=Count(
-                "shifts__participations",
-                filter=Q(
-                    shifts__participations__state=AbstractParticipation.States.REQUESTED,
-                    can_change=True,
-                ),
-            ),
-            **{
-                f"state_{state}_count": Count(
-                    "shifts__participations",
-                    filter=Q(
-                        shifts__participations__localparticipation__user=self.request.user,
-                        shifts__participations__state=state,
-                    ),
-                )
-                for state in AbstractParticipation.States
-            },
-        )
-        return qs
-
     def get_calendar_month(self):
         "Return, even if the form is invalid, a tuple of year, month for the calendar to show"
         if self.is_valid() and (date := self.cleaned_data.get("date")):
@@ -246,6 +213,25 @@ def get_queryset(self):
                     output_field=BooleanField(),
                 )
             )
+            .annotate(
+                pending_disposition_count=Count(
+                    "shifts__participations",
+                    filter=Q(
+                        shifts__participations__state=AbstractParticipation.States.REQUESTED,
+                        can_change=True,
+                    ),
+                ),
+                **{
+                    f"state_{state}_count": Count(
+                        "shifts__participations",
+                        filter=Q(
+                            shifts__participations__localparticipation__user=self.request.user,
+                            shifts__participations__state=state,
+                        ),
+                    )
+                    for state in AbstractParticipation.States
+                },
+            )
             .select_related("type")
             .prefetch_related("shifts")
             .prefetch_related(Prefetch("shifts__participations"))


Test patch: