diff --git a/partner_catalog/api/v1/filters.py b/partner_catalog/api/v1/filters.py index 0aaa301..c0c3e23 100644 --- a/partner_catalog/api/v1/filters.py +++ b/partner_catalog/api/v1/filters.py @@ -2,6 +2,7 @@ import django_filters +from rest_framework.filters import OrderingFilter from partner_catalog.models import Partner, PartnerCatalog @@ -52,3 +53,41 @@ class Meta: fields = [ "partner", ] + + +class CatalogCourseOrderingFilter(OrderingFilter): + ordering_map = { + # Course dates + "course_start": "course_overview__start", + "course_end": "course_overview__end", + + # Enrollment dates + "enrollment_start": "course_overview__enrollment_start", + "enrollment_end": "course_overview__enrollment_end", + + # Metrics + "enrollments": "enrollments_count", + "certified": "certified_count", + + # Base fields + "position": "position", + "id": "id", + } + + def get_ordering(self, request, queryset, view): + params = request.query_params.get(self.ordering_param) + if not params: + return self.get_default_ordering(view) + + fields = [p.strip() for p in params.split(",")] + ordering = [] + + for field in fields: + desc = field.startswith("-") + key = field[1:] if desc else field + mapped = self.ordering_map.get(key) + + if mapped: + ordering.append(f"-{mapped}" if desc else mapped) + + return ordering diff --git a/partner_catalog/api/v1/views.py b/partner_catalog/api/v1/views.py index 89968b2..e514fad 100644 --- a/partner_catalog/api/v1/views.py +++ b/partner_catalog/api/v1/views.py @@ -8,7 +8,7 @@ from rest_framework.parsers import MultiPartParser from rest_framework.response import Response -from partner_catalog.api.v1.filters import PartnerCatalogFilter, PartnerFilter +from partner_catalog.api.v1.filters import CatalogCourseOrderingFilter, PartnerCatalogFilter, PartnerFilter from partner_catalog.api.v1.mixins import InjectNestedFKMixin from partner_catalog.api.v1.schemas import ( add_courses_schema, @@ -300,12 +300,17 @@ class CatalogCourseViewSet( filter_backends = [ DjangoFilterBackend, filters.SearchFilter, - filters.OrderingFilter, + CatalogCourseOrderingFilter, ] filterset_fields = ["catalog", "course_overview"] search_fields = ["course_overview__display_name"] - ordering_fields = ["id", "position"] ordering = ["position"] + ordering_fields = [ + "id", "position", + "course_start", "course_end", + "enrollment_start", "enrollment_end", + "enrollments", "certified", + ] # Mixin config nested_lookup_kwarg = "catalog_pk"