From fd6abe585f467aaa302cd3ead712acbedb0d5499 Mon Sep 17 00:00:00 2001 From: funnywolf Date: Sat, 11 Jul 2026 09:09:09 +0800 Subject: [PATCH] Disable related count sorting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- backend/apps/alerts/views.py | 30 +++++++------------ backend/apps/artifacts/views.py | 9 +----- backend/apps/cases/views.py | 16 +--------- .../management/commands/run_perf_benchmark.py | 24 ++++----------- frontend/src/config/resources.tsx | 4 --- 5 files changed, 18 insertions(+), 65 deletions(-) diff --git a/backend/apps/alerts/views.py b/backend/apps/alerts/views.py index 393f6a8..3b595c9 100644 --- a/backend/apps/alerts/views.py +++ b/backend/apps/alerts/views.py @@ -37,7 +37,6 @@ class AlertViewSet(AuditActorMixin, viewsets.ModelViewSet): ordering_fields = ( "created_at", "updated_at", - "artifact_count", "severity", "confidence", "impact", @@ -83,25 +82,18 @@ class AlertViewSet(AuditActorMixin, viewsets.ModelViewSet): "created_at": "date", } - def is_ordering_by_artifact_count(self): - raw_ordering = self.request.query_params.get("ordering", "") - return any(field.strip().lstrip("-") == "artifact_count" for field in raw_ordering.split(",")) - def annotate_list_counts(self, queryset): - if self.is_ordering_by_artifact_count(): - queryset = queryset.annotate(artifact_count=Count("artifacts", distinct=True)) - else: - artifact_count = ( - Alert.artifacts.through.objects - .filter(alert_id=OuterRef("pk")) - .order_by() - .values("alert_id") - .annotate(count=Count("artifact_id")) - .values("count")[:1] - ) - queryset = queryset.annotate( - artifact_count=Coalesce(Subquery(artifact_count, output_field=IntegerField()), Value(0)) - ) + artifact_count = ( + Alert.artifacts.through.objects + .filter(alert_id=OuterRef("pk")) + .order_by() + .values("alert_id") + .annotate(count=Count("artifact_id")) + .values("count")[:1] + ) + queryset = queryset.annotate( + artifact_count=Coalesce(Subquery(artifact_count, output_field=IntegerField()), Value(0)) + ) enrichment_count = ( Enrichment.objects diff --git a/backend/apps/artifacts/views.py b/backend/apps/artifacts/views.py index 226137c..f2ea58f 100644 --- a/backend/apps/artifacts/views.py +++ b/backend/apps/artifacts/views.py @@ -19,7 +19,7 @@ class ArtifactViewSet(AuditActorMixin, viewsets.ModelViewSet): lookup_field = "id" filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter, AdvancedFilterBackend) search_fields = ("artifact_id", "value", "name", "type", "role") - ordering_fields = ("created_at", "updated_at", "type", "role", "alert_count") + ordering_fields = ("created_at", "updated_at", "type", "role") filterset_fields = ("type", "role", "alerts__id") advanced_filter_fields = { "artifact_id": "text", @@ -31,14 +31,7 @@ class ArtifactViewSet(AuditActorMixin, viewsets.ModelViewSet): "updated_at": "date", } - def is_ordering_by_alert_count(self): - raw_ordering = self.request.query_params.get("ordering", "") - return any(field.strip().lstrip("-") == "alert_count" for field in raw_ordering.split(",")) - def annotate_alert_count(self, queryset): - if self.is_ordering_by_alert_count(): - return queryset.annotate(alert_count=Count("alerts", distinct=True)) - alert_count = ( Artifact.alerts.through.objects .filter(artifact_id=OuterRef("pk")) diff --git a/backend/apps/cases/views.py b/backend/apps/cases/views.py index 44bc6da..fc2fb10 100644 --- a/backend/apps/cases/views.py +++ b/backend/apps/cases/views.py @@ -1,4 +1,4 @@ -from django.db.models import Count, DateTimeField, IntegerField, Min, OuterRef, Subquery, Value +from django.db.models import Count, DateTimeField, IntegerField, OuterRef, Subquery, Value from django.db.models.functions import Coalesce from django_filters.rest_framework import DjangoFilterBackend from rest_framework import viewsets, permissions @@ -29,8 +29,6 @@ class CaseViewSet(AuditActorMixin, viewsets.ModelViewSet): "updated_at", "acknowledged_time", "closed_time", - "alert_count", - "playbook_count", "severity", "severity_ai", "priority", @@ -74,19 +72,7 @@ class CaseViewSet(AuditActorMixin, viewsets.ModelViewSet): "correlation_uid": "text", } - def is_ordering_by_relation_count(self): - raw_ordering = self.request.query_params.get("ordering", "") - ordering_fields = {field.strip().lstrip("-") for field in raw_ordering.split(",")} - return bool(ordering_fields & {"alert_count", "playbook_count"}) - def annotate_list_metrics(self, queryset): - if self.is_ordering_by_relation_count(): - return queryset.annotate( - alert_count=Count("alerts", distinct=True), - playbook_count=Count("playbooks", distinct=True), - first_alert_seen_time=Min("alerts__first_seen_time"), - ) - alert_count = ( Alert.objects .filter(case_id=OuterRef("pk")) diff --git a/backend/apps/common/management/commands/run_perf_benchmark.py b/backend/apps/common/management/commands/run_perf_benchmark.py index 5d7e632..c6d67ba 100644 --- a/backend/apps/common/management/commands/run_perf_benchmark.py +++ b/backend/apps/common/management/commands/run_perf_benchmark.py @@ -8,7 +8,7 @@ from types import SimpleNamespace from django.conf import settings from django.core.management.base import BaseCommand, CommandError from django.db import connection, reset_queries -from django.db.models import CharField, Count, DateTimeField, IntegerField, Min, OuterRef, Q, Subquery, Value +from django.db.models import CharField, Count, DateTimeField, IntegerField, OuterRef, Q, Subquery, Value from django.db.models.functions import Cast, Coalesce, Concat from django.utils import timezone @@ -159,13 +159,7 @@ class Command(BaseCommand): } def scenarios(self, *, page_size, deep_offset): - def case_queryset(*, with_count_order=False): - if with_count_order: - return Case.objects.select_related("assignee").annotate( - alert_count=Count("alerts", distinct=True), - playbook_count=Count("playbooks", distinct=True), - first_alert_seen_time=Min("alerts__first_seen_time"), - ).order_by("-created_at") + def case_queryset(): alert_count = ( Alert.objects .filter(case_id=OuterRef("pk")) @@ -194,15 +188,10 @@ class Command(BaseCommand): first_alert_seen_time=Subquery(first_alert_seen_time, output_field=DateTimeField()), ).order_by("-created_at") - def alert_queryset(*, with_artifact_count=False): - queryset = Alert.objects.select_related("case").prefetch_related("artifacts") - if with_artifact_count: - queryset = queryset.annotate(artifact_count=Count("artifacts", distinct=True)) - return queryset.order_by("-created_at") + def alert_queryset(): + return Alert.objects.select_related("case").prefetch_related("artifacts").order_by("-created_at") - def artifact_queryset(*, with_alert_count_order=False): - if with_alert_count_order: - return Artifact.objects.annotate(alert_count=Count("alerts", distinct=True)).order_by("-created_at") + def artifact_queryset(): alert_count = ( Artifact.alerts.through.objects .filter(artifact_id=OuterRef("pk")) @@ -239,19 +228,16 @@ class Command(BaseCommand): ("cases.default_page", lambda: list_count(case_queryset())), ("cases.deep_page", lambda: list_count(case_queryset()[deep_offset:deep_offset + page_size])), ("cases.filter_status_severity", lambda: list_count(case_queryset().filter(status__in=["New", "In Progress"], severity__in=["High", "Critical"]))), - ("cases.order_alert_count", lambda: list_count(case_queryset(with_count_order=True).order_by("-alert_count", "-created_at"))), ("cases.search_hot", lambda: list_count(case_queryset().filter(Q(case_id__icontains=HOT_SEARCH_TOKEN) | Q(title__icontains=HOT_SEARCH_TOKEN) | Q(description__icontains=HOT_SEARCH_TOKEN) | Q(summary__icontains=HOT_SEARCH_TOKEN) | Q(correlation_uid__icontains=HOT_SEARCH_TOKEN)))), ("cases.search_rare", lambda: list_count(case_queryset().filter(Q(title__icontains=RARE_SEARCH_TOKEN) | Q(description__icontains=RARE_SEARCH_TOKEN)))), ("alerts.default_page", lambda: list_count(alert_queryset())), ("alerts.filter_status_severity", lambda: list_count(alert_queryset().filter(status__in=["New", "In Progress"], severity__in=["High", "Critical"]))), ("alerts.filter_product_risk", lambda: list_count(alert_queryset().filter(product_category="IAM", risk_level__in=["High", "Critical"]))), ("alerts.order_first_seen", lambda: list_count(alert_queryset().order_by("-first_seen_time", "-id"))), - ("alerts.order_artifact_count", lambda: list_count(alert_queryset(with_artifact_count=True).order_by("-artifact_count", "-created_at"))), ("alerts.search_hot", lambda: list_count(alert_queryset().filter(Q(alert_id__icontains=HOT_SEARCH_TOKEN) | Q(title__icontains=HOT_SEARCH_TOKEN) | Q(desc__icontains=HOT_SEARCH_TOKEN) | Q(rule_name__icontains=HOT_SEARCH_TOKEN) | Q(source_uid__icontains=HOT_SEARCH_TOKEN)))), ("alerts.search_rare", lambda: list_count(alert_queryset().filter(Q(title__icontains=RARE_SEARCH_TOKEN) | Q(rule_name__icontains=RARE_SEARCH_TOKEN)))), ("artifacts.default_page", lambda: list_count(artifact_queryset())), ("artifacts.filter_type_role", lambda: list_count(artifact_queryset().filter(type="Hostname", role__in=["Actor", "Target"]))), - ("artifacts.order_alert_count", lambda: list_count(artifact_queryset(with_alert_count_order=True).order_by("-alert_count", "-created_at"))), ("artifacts.search_hot", lambda: list_count(artifact_queryset().filter(Q(artifact_id__icontains=HOT_SEARCH_TOKEN) | Q(value__icontains=HOT_SEARCH_TOKEN) | Q(name__icontains=HOT_SEARCH_TOKEN) | Q(type__icontains=HOT_SEARCH_TOKEN) | Q(role__icontains=HOT_SEARCH_TOKEN)))), ("artifacts.search_rare", lambda: list_count(artifact_queryset().filter(value__icontains=RARE_SEARCH_TOKEN))), ("dashboard.24h", lambda: len(build_dashboard_overview("24h"))), diff --git a/frontend/src/config/resources.tsx b/frontend/src/config/resources.tsx index d0b1eb9..f67f33e 100644 --- a/frontend/src/config/resources.tsx +++ b/frontend/src/config/resources.tsx @@ -413,14 +413,12 @@ export const resourceConfigs: Record> = { column('alerts_link', 'Alerts', L132, { dataIndex: 'alert_count', defaultVisible: true, - sorter: true, openRecordTab: 'alerts', render: viewRelatedLabel, }), column('playbooks_link', 'Playbooks', L132, { dataIndex: 'playbook_count', defaultVisible: true, - sorter: true, openRecordTab: 'playbooks', render: viewRelatedLabel, }), @@ -585,7 +583,6 @@ export const resourceConfigs: Record> = { column('artifacts_link', 'Artifacts', L132, { dataIndex: 'artifact_count', defaultVisible: true, - sorter: true, openRecordTab: 'artifacts', render: viewRelatedLabel, }), @@ -703,7 +700,6 @@ export const resourceConfigs: Record> = { column('alerts_link', 'Alerts', L160, { dataIndex: 'alert_count', defaultVisible: true, - sorter: true, openRecordTab: 'alerts', render: viewRelatedLabel, }),