diff --git a/backend/coreapp/views/scratch.py b/backend/coreapp/views/scratch.py index 25588f70..1b314e69 100644 --- a/backend/coreapp/views/scratch.py +++ b/backend/coreapp/views/scratch.py @@ -11,6 +11,8 @@ import django_filters from coreapp import compilers, platforms from django.core.files import File +from django.db.models import F, FloatField, When, Case, Value +from django.db.models.functions import Cast from django.http import HttpResponse, QueryDict from rest_framework import filters, mixins, serializers, status from rest_framework.decorators import action @@ -310,7 +312,16 @@ class ScratchViewSet( mixins.ListModelMixin, GenericViewSet, # type: ignore ): - queryset = Scratch.objects.all() + match_percent = Case( + When(max_score__lte=0, then=Value(0.0)), + When(score__lt=0, then=Value(0.0)), + When(score__gt=F("max_score"), then=Value(0.0)), + When(score=0, then=Value(1.0)), + When(match_override=True, then=Value(1.0)), + default=1.0 - (F("score") / Cast("max_score", FloatField())), + ) + + queryset = Scratch.objects.all().annotate(match_percent=match_percent) pagination_class = ScratchPagination filterset_fields = ["platform", "compiler", "preset"] filter_backends = [ @@ -319,7 +330,7 @@ class ScratchViewSet( filters.OrderingFilter, ] search_fields = ["name", "diff_label"] - ordering_fields = ["creation_time", "last_updated", "score"] + ordering_fields = ["creation_time", "last_updated", "score", "match_percent"] def get_serializer_class(self) -> type[serializers.ModelSerializer[Scratch]]: if self.action == "list": diff --git a/frontend/src/components/Sort.tsx b/frontend/src/components/Sort.tsx index 27a4d9b2..f27b9e61 100644 --- a/frontend/src/components/Sort.tsx +++ b/frontend/src/components/Sort.tsx @@ -5,8 +5,8 @@ export enum SortMode { NEWEST_FIRST = "-creation_time", OLDEST_FIRST = "creation_time", LAST_UPDATED = "-last_updated", - LEAST_MATCHED = "-score", - MOST_MATCHED = "score", + LEAST_MATCHED = "match_percent", + MOST_MATCHED = "-match_percent", } export function produceSortFunction(sortMode: SortMode): (a: TerseScratch, b: TerseScratch) => number {