Optimize alert and alert group public api endpoints, add filter by id (#1274)

# What this PR does

## Which issue(s) this PR fixes

## Checklist

- [ ] Tests updated
- [ ] Documentation added
- [ ] `CHANGELOG.md` updated

---------

Co-authored-by: Joey Orlando <joey.orlando@grafana.com>
This commit is contained in:
Ildar Iskhakov 2023-02-03 17:05:08 +08:00 committed by GitHub
parent 038310829b
commit 335c8fe65b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 9 deletions

View file

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Optimize alert and alert group public api endpoints and add filter by id ([1274](https://github.com/grafana/oncall/pull/1274)
## v1.1.21 (2023-02-02)
### Added
@ -12,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add [`django-dbconn-retry` library](https://github.com/jdelic/django-dbconn-retry) to `INSTALLED_APPS` to attempt
to alleviate occasional `django.db.utils.OperationalError` errors
- Improve alerts and alert group endpoint response time in internal API with caching ([1261](https://github.com/grafana/oncall/pull/1261))
- Optimize alert and alert group public api endpoints and add filter by id ([1274](https://github.com/grafana/oncall/pull/1274)
- Added Coming Soon for iOS on Mobile App screen
### Fixed

View file

@ -44,6 +44,7 @@ The above command returns JSON structured in the following way:
These available filter parameters should be provided as `GET` arguments:
- `id`
- `route_id`
- `integration_id`
- `state`

View file

@ -104,6 +104,7 @@ The above command returns JSON structured in the following way:
The following available filter parameters should be provided as `GET` arguments:
- `id`
- `alert_group_id`
- `search`—string-based inclusion search by alert payload

View file

@ -13,12 +13,11 @@ class IncidentSerializer(EagerLoadingMixin, serializers.ModelSerializer):
route_id = serializers.SerializerMethodField()
created_at = serializers.DateTimeField(source="started_at")
alerts_count = serializers.SerializerMethodField()
title = serializers.SerializerMethodField()
title = serializers.CharField(source="web_title_cache")
state = serializers.SerializerMethodField()
SELECT_RELATED = ["channel", "channel_filter", "slack_message"]
SELECT_RELATED = ["channel", "channel_filter", "slack_message", "channel__organization"]
PREFETCH_RELATED = [
"alerts",
Prefetch(
"telegram_messages",
TelegramMessage.objects.filter(chat_id__startswith="-", message_type=TelegramMessage.ALERT_GROUP_MESSAGE),
@ -42,10 +41,8 @@ class IncidentSerializer(EagerLoadingMixin, serializers.ModelSerializer):
]
def get_alerts_count(self, obj):
return len(obj.alerts.all())
def get_title(self, obj):
return obj.alerts.all()[0].title
# alerts_count is an annotated field added in get_queryset
return obj.alerts_count
def get_state(self, obj):
return obj.state

View file

@ -1,5 +1,6 @@
from django.db.models import CharField
from django.db.models.functions import Cast
from django_filters import rest_framework as filters
from rest_framework import mixins
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import GenericViewSet
@ -12,6 +13,10 @@ from common.api_helpers.mixins import RateLimitHeadersMixin
from common.api_helpers.paginators import FiftyPageSizePaginator
class AlertFilter(filters.FilterSet):
id = filters.CharFilter(field_name="public_primary_key")
class AlertView(RateLimitHeadersMixin, mixins.ListModelMixin, GenericViewSet):
authentication_classes = (ApiTokenAuthentication,)
permission_classes = (IsAuthenticated,)
@ -22,6 +27,9 @@ class AlertView(RateLimitHeadersMixin, mixins.ListModelMixin, GenericViewSet):
serializer_class = AlertSerializer
pagination_class = FiftyPageSizePaginator
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = AlertFilter
def get_queryset(self):
alert_group_id = self.request.query_params.get("alert_group_id", None)
search = self.request.query_params.get("search", None)

View file

@ -1,4 +1,4 @@
from django.db.models import Q
from django.db.models import Count, Q
from django_filters import rest_framework as filters
from rest_framework import mixins, status
from rest_framework.exceptions import NotFound
@ -29,6 +29,8 @@ class IncidentByTeamFilter(ByTeamModelFieldFilterMixin, filters.FilterSet):
method=ByTeamModelFieldFilterMixin.filter_model_field_with_single_value.__name__,
)
id = filters.CharFilter(field_name="public_primary_key")
class IncidentView(RateLimitHeadersMixin, mixins.ListModelMixin, mixins.DestroyModelMixin, GenericViewSet):
authentication_classes = (ApiTokenAuthentication,)
@ -77,7 +79,7 @@ class IncidentView(RateLimitHeadersMixin, mixins.ListModelMixin, mixins.DestroyM
raise BadRequest(detail={"state": f"Must be one of the following: {valid_choices_text}"})
queryset = self.serializer_class.setup_eager_loading(queryset)
queryset = queryset.annotate(alerts_count=Count("alerts"))
return queryset
def get_object(self):