Skip to content

Instantly share code, notes, and snippets.

@Object905
Created July 13, 2021 17:17
Show Gist options
  • Save Object905/d746a75487d0bc8d52e33ba9e713ef1b to your computer and use it in GitHub Desktop.
Save Object905/d746a75487d0bc8d52e33ba9e713ef1b to your computer and use it in GitHub Desktop.
from typing import Generic, TypeVar
import strawberry
from django.core.paginator import EmptyPage, Page, PageNotAnInteger, Paginator
from django.db.models.query import QuerySet
T = TypeVar("T")
MAX_PAGE_SIZE = 100
@strawberry.interface
class PageInput:
page: int = 1
page_size: int = 10
def paginate(self, qs: QuerySet[T]) -> "Paginated[T]":
return Paginated.paginate(qs, page=self.page, page_size=self.page_size)
@strawberry.interface
class PageInfo:
page: int
total_pages: int
total_items: int
has_next: bool
has_prev: bool
@strawberry.type
class Paginated(Generic[T], PageInfo):
page: int
total_pages: int
total_items: int
has_next: bool
has_prev: bool
data: list[T]
@classmethod
def paginate(
cls, qs: QuerySet[T], page: int = 1, page_size: int = 10
) -> "Paginated[T]":
page = cls.get_page(qs, page_size, page)
return cls(
page=page.number,
total_pages=page.paginator.num_pages,
total_items=page.paginator.count,
has_next=page.has_next(),
has_prev=page.has_previous(),
data=page.object_list,
)
@staticmethod
def get_page(qs: QuerySet, page_size: int, page: int) -> Page:
if page_size > MAX_PAGE_SIZE:
page_size = MAX_PAGE_SIZE
p = Paginator(qs, page_size)
try:
page_obj = p.page(page)
except PageNotAnInteger:
page_obj = p.page(1)
except EmptyPage:
page_obj = p.page(p.num_pages)
return page_obj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment