diff --git a/engine/apps/api/serializers/schedule_base.py b/engine/apps/api/serializers/schedule_base.py index b3e1858d..c2eb6ea6 100644 --- a/engine/apps/api/serializers/schedule_base.py +++ b/engine/apps/api/serializers/schedule_base.py @@ -76,7 +76,8 @@ class ScheduleBaseSerializer(EagerLoadingMixin, serializers.ModelSerializer): def get_number_of_escalation_chains(self, obj): # num_escalation_chains param added in queryset via annotate. Check ScheduleView.get_queryset # return 0 for just created schedules - return getattr(obj, "num_escalation_chains", 0) + num = getattr(obj, "num_escalation_chains", 0) + return num or 0 def validate(self, attrs): if "slack_channel_id" in attrs: diff --git a/engine/apps/api/views/schedule.py b/engine/apps/api/views/schedule.py index 4bc5764e..9c52a69c 100644 --- a/engine/apps/api/views/schedule.py +++ b/engine/apps/api/views/schedule.py @@ -13,7 +13,7 @@ from rest_framework.permissions import IsAuthenticated from rest_framework.views import Response from rest_framework.viewsets import ModelViewSet -from apps.alerts.models import EscalationChain +from apps.alerts.models import EscalationChain, EscalationPolicy from apps.api.permissions import MODIFY_ACTIONS, READ_ACTIONS, ActionPermission, AnyRole, IsAdmin, IsAdminOrEditor from apps.api.serializers.schedule_base import ScheduleFastSerializer from apps.api.serializers.schedule_polymorphic import ( @@ -108,22 +108,28 @@ class ScheduleView( slack_team_identity=organization.slack_team_identity, slack_id=OuterRef("channel"), ) + escalation_policies = ( + EscalationPolicy.objects.values("notify_schedule") + .order_by("notify_schedule") + .annotate(num_escalation_chains=Count("notify_schedule")) + .filter(notify_schedule=OuterRef("id")) + ) queryset = queryset.annotate( slack_channel_name=Subquery(slack_channels.values("name")[:1]), slack_channel_pk=Subquery(slack_channels.values("public_primary_key")[:1]), - num_escalation_chains=Count( - "escalation_policies__escalation_chain", - distinct=True, - ), + num_escalation_chains=Subquery(escalation_policies.values("num_escalation_chains")[:1]), ) return queryset def get_queryset(self): is_short_request = self.request.query_params.get("short", "false") == "true" organization = self.request.auth.organization - queryset = OnCallSchedule.objects.filter( - organization=organization, - team=self.request.user.current_team, + queryset = OnCallSchedule.objects.filter(organization=organization, team=self.request.user.current_team).defer( + # avoid requesting large text fields which are not used when listing schedules + "cached_ical_file_primary", + "prev_ical_file_primary", + "cached_ical_file_overrides", + "prev_ical_file_overrides", ) if not is_short_request: queryset = self._annotate_queryset(queryset)