Coverage for api/utils/pagination.py: 100%
22 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 06:14 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 06:14 +0000
1from rest_framework.pagination import PageNumberPagination
2from rest_framework.response import Response
5class StandardPagination(PageNumberPagination):
6 page_size_query_param = "page_size"
7 page_query_param = "page"
9 result_count: int | None
10 page_count: int | None
11 page: int
12 warnings: list[dict]
14 def __init__(self, *args, **kwargs):
15 super().__init__(*args, **kwargs)
16 self.result_count = None # populated later
17 self.page_count = None # populated later
18 self.page = 1 # default, gets updated when necessary
19 self.warnings = [] # populated later as needed
21 def get_paginated_response(self, data):
22 response = {
23 "result_count": self.result_count,
24 "page_count": self.page_count,
25 "page_size": self.page_size,
26 "page": self.page,
27 "results": data,
28 }
29 return Response(
30 (
31 {
32 # Put ``warnings`` first so it is as visible as possible.
33 "warnings": list(self.warnings),
34 }
35 if self.warnings
36 else {}
37 )
38 | response
39 )
41 def get_paginated_response_schema(self, schema):
42 """
43 Get the schema of the paginated response, used by `drf-spectacular` to
44 generate the documentation of the paginated search results response.
45 """
47 field_descriptions = {
48 "result_count": (
49 "The total number of items returned by search result.",
50 10000,
51 ),
52 "page_count": ("The total number of pages returned by search result.", 20),
53 "page_size": ("The number of items per page.", 20),
54 "page": ("The current page number returned in the response.", 1),
55 }
57 properties = {
58 field: {
59 "type": "integer",
60 "description": description,
61 "example": example,
62 }
63 for field, (description, example) in field_descriptions.items()
64 } | {
65 "results": schema,
66 "warnings": {
67 "type": "array",
68 "items": {
69 "type": "object",
70 },
71 "description": (
72 "Warnings pertinent to the request. "
73 "If there are no warnings, this property will not be present on the response. "
74 "Warnings are non-critical problems with the request. "
75 "Responses with warnings should be treated as unstable. "
76 "Warning descriptions must not be treated as machine readable "
77 "and their schema can change at any time."
78 ),
79 "example": [
80 {
81 "code": "partially invalid request parameter",
82 "message": (
83 "Some of the request parameters were bad, "
84 "but we were able to process the request. "
85 "Here's some information that might help you "
86 "fix the problem for future requests."
87 ),
88 }
89 ],
90 },
91 }
93 return {
94 "type": "object",
95 "properties": properties,
96 "required": list(set(properties.keys()) - {"warnings"}),
97 }