forked from enviPath/enviPy
## Major Changes - Implement a REST style API app in epapi - Currently implements a GET method for all entity types in the browse menu (both package level and global) - Provides paginated results per default with query style filtering for reviewed vs unreviewed. - Provides new paginated templates with thin wrappers per entity types for easier maintainability - Implements e2e tests for the API ## Minor changes - Added more comprehensive gitignore to cover coverage reports and other test/node.js etc. data. - Add additional CI file for API tests that only gets triggered on API relevant changes. ## ⚠️ Currently only works with session-based authentication. Token based will be added in new PR. Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Co-authored-by: jebus <lorsbach@envipath.com> Reviewed-on: enviPath/enviPy#243 Co-authored-by: Tobias O <tobias.olenyi@envipath.com> Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
import math
|
|
from typing import Any, Generic, List, TypeVar
|
|
|
|
from django.db.models import QuerySet
|
|
from ninja import Schema
|
|
from ninja.pagination import PageNumberPagination
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
class EnhancedPageNumberPagination(PageNumberPagination):
|
|
class Output(Schema, Generic[T]):
|
|
items: List[T]
|
|
page: int
|
|
page_size: int
|
|
total_items: int
|
|
total_pages: int
|
|
|
|
def paginate_queryset(
|
|
self,
|
|
queryset: QuerySet,
|
|
pagination: PageNumberPagination.Input,
|
|
**params: Any,
|
|
) -> Any:
|
|
page_size = self._get_page_size(pagination.page_size)
|
|
offset = (pagination.page - 1) * page_size
|
|
total_items = self._items_count(queryset)
|
|
total_pages = math.ceil(total_items / page_size) if page_size > 0 else 0
|
|
|
|
return {
|
|
"items": queryset[offset : offset + page_size],
|
|
"page": pagination.page,
|
|
"page_size": page_size,
|
|
"total_items": total_items,
|
|
"total_pages": total_pages,
|
|
}
|
|
|
|
async def apaginate_queryset(
|
|
self,
|
|
queryset: QuerySet,
|
|
pagination: PageNumberPagination.Input,
|
|
**params: Any,
|
|
) -> Any:
|
|
page_size = self._get_page_size(pagination.page_size)
|
|
offset = (pagination.page - 1) * page_size
|
|
total_items = await self._aitems_count(queryset)
|
|
total_pages = math.ceil(total_items / page_size) if page_size > 0 else 0
|
|
|
|
if isinstance(queryset, QuerySet):
|
|
items = [obj async for obj in queryset[offset : offset + page_size]]
|
|
else:
|
|
items = queryset[offset : offset + page_size]
|
|
|
|
return {
|
|
"items": items,
|
|
"page": pagination.page,
|
|
"page_size": page_size,
|
|
"total_items": total_items,
|
|
"total_pages": total_pages,
|
|
}
|