Files
bugsink/releases/api_views.py
Klaas van Schelven 7bf906a8fd API: Release Pagination
this also fixes the index on releases (since they are always ordered
in the context of a particular project, this should be part of the
index)

See #146
2025-09-11 16:53:15 +02:00

48 lines
1.7 KiB
Python

from rest_framework import viewsets
from rest_framework.exceptions import ValidationError
from bugsink.api_pagination import AscDescCursorPagination
from .models import Release
from .serializers import ReleaseListSerializer, ReleaseDetailSerializer, ReleaseCreateSerializer
class ReleasePagination(AscDescCursorPagination):
# Cursor pagination requires an indexed, mostly-stable ordering field. We use `digest_order`: We require
# ?project=<id> and have a composite (project_id, date_released) index, so ORDER BY date_released after filtering by
# project is fast and cursor-stable. (also note that date_released generally comes in in-order).
base_ordering = ("date_released",)
page_size = 250
default_direction = "desc"
class ReleaseViewSet(viewsets.ModelViewSet):
"""
LIST requires: ?project=<id>
Ordered by sort_epoch.
CREATE allowed. DELETE potential TODO.
"""
queryset = Release.objects.all()
serializer_class = ReleaseListSerializer
http_method_names = ["get", "post", "head", "options"]
pagination_class = ReleasePagination
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
if self.action != "list":
return queryset
query_params = self.request.query_params
project_id = query_params.get("project")
if not project_id:
raise ValidationError({"project": ["This field is required."]})
return queryset.filter(project=project_id)
def get_serializer_class(self):
if self.action == "create":
return ReleaseCreateSerializer
if self.action == "retrieve":
return ReleaseDetailSerializer
return ReleaseListSerializer