Skip to content

fastack.mixins

ListControllerMixin

Source code in fastack/mixins.py
class ListControllerMixin:
    pagination_class: Type[Pagination] = PageNumberPagination

    def paginate(self, data: Sequence, page: int = 1, page_size: int = 10) -> Sequence:
        """
        Paginate data.

        Args:
            data: Data to be paginated.
            page: Page number.
            page_size: Page size.

        """

        if self.pagination_class:
            data = self.pagination_class(page, page_size).paginate(data)

        results = []
        for o in data:
            o = self.serialize_data(o)  # type: ignore[attr-defined]
            o = jsonable_encoder(o)
            results.append(o)

        return results

    def get_total_data(self, data: Any):
        """
        Get total data.
        Might be useful if the data is a QuerySet or something that can compute :)
        """

        return len(data)

    def get_total_page(self, total: int, page_size: int = 10) -> List[int]:
        """
        Get total pages.

        Args:
            total: Total data.
            page_size: Page size.
        """

        if total == 0:
            return [1]  # pragma: no cover

        return list(
            range(
                1,
                (
                    total // page_size + 1
                    if total % page_size != 0
                    else total // page_size
                )
                + 1,
            )
        )

    def get_paginated_response(
        self,
        data: Sequence,
        page: int = 1,
        page_size: int = 10,
        *,
        status: int = 200,
        headers: Optional[dict] = None,
        **kwargs: Any,
    ) -> JSONResponse:
        """
        Return a paginated response.

        Args:
            data: Data to be paginated.
            page: Page number.
            page_size: Page size.
            status: HTTP status code.
            headers: HTTP headers.
            **kwargs (optional): Additional arguments to be passed to the JSONResponse.
        """

        # Counting all pages
        total_data = self.get_total_data(data)
        pages = self.get_total_page(total_data, page_size)
        prev_page = page - 1
        if prev_page not in pages:
            prev_page = None  # type: ignore[assignment]

        next_page = page + 1
        if next_page not in pages:
            next_page = None  # type: ignore[assignment]

        # Get data per page
        data = self.paginate(data, page, page_size)
        total = self.get_total_data(data)
        content = {
            "total": total,
            "paging": {"next": next_page, "prev": prev_page, "pages": pages},
            "data": data,
        }
        return JSONResponse(content, status_code=status, headers=headers, **kwargs)

pagination_class (Pagination)

Pagination class for page number

Source code in fastack/mixins.py
class PageNumberPagination(Pagination):
    """
    Pagination class for page number
    """

    def __init__(self, page: int, page_size: int):
        self.page = page
        self.page_size = page_size

    def get_offset(self) -> int:
        return self.page_size * (self.page - 1)

    def get_limit(self) -> int:
        return self.page_size

    def paginate(self, data: Sequence) -> Sequence:
        offset = self.get_offset()
        limit = self.get_limit()
        return data[offset : offset + limit]

get_paginated_response(self, data, page=1, page_size=10, *, status=200, headers=None, **kwargs)

Return a paginated response.

Parameters:

Name Type Description Default
data Sequence

Data to be paginated.

required
page int

Page number.

1
page_size int

Page size.

10
status int

HTTP status code.

200
headers Optional[dict]

HTTP headers.

None
**kwargs optional

Additional arguments to be passed to the JSONResponse.

{}
Source code in fastack/mixins.py
def get_paginated_response(
    self,
    data: Sequence,
    page: int = 1,
    page_size: int = 10,
    *,
    status: int = 200,
    headers: Optional[dict] = None,
    **kwargs: Any,
) -> JSONResponse:
    """
    Return a paginated response.

    Args:
        data: Data to be paginated.
        page: Page number.
        page_size: Page size.
        status: HTTP status code.
        headers: HTTP headers.
        **kwargs (optional): Additional arguments to be passed to the JSONResponse.
    """

    # Counting all pages
    total_data = self.get_total_data(data)
    pages = self.get_total_page(total_data, page_size)
    prev_page = page - 1
    if prev_page not in pages:
        prev_page = None  # type: ignore[assignment]

    next_page = page + 1
    if next_page not in pages:
        next_page = None  # type: ignore[assignment]

    # Get data per page
    data = self.paginate(data, page, page_size)
    total = self.get_total_data(data)
    content = {
        "total": total,
        "paging": {"next": next_page, "prev": prev_page, "pages": pages},
        "data": data,
    }
    return JSONResponse(content, status_code=status, headers=headers, **kwargs)

get_total_data(self, data)

Get total data. Might be useful if the data is a QuerySet or something that can compute :)

Source code in fastack/mixins.py
def get_total_data(self, data: Any):
    """
    Get total data.
    Might be useful if the data is a QuerySet or something that can compute :)
    """

    return len(data)

get_total_page(self, total, page_size=10)

Get total pages.

Parameters:

Name Type Description Default
total int

Total data.

required
page_size int

Page size.

10
Source code in fastack/mixins.py
def get_total_page(self, total: int, page_size: int = 10) -> List[int]:
    """
    Get total pages.

    Args:
        total: Total data.
        page_size: Page size.
    """

    if total == 0:
        return [1]  # pragma: no cover

    return list(
        range(
            1,
            (
                total // page_size + 1
                if total % page_size != 0
                else total // page_size
            )
            + 1,
        )
    )

paginate(self, data, page=1, page_size=10)

Paginate data.

Parameters:

Name Type Description Default
data Sequence

Data to be paginated.

required
page int

Page number.

1
page_size int

Page size.

10
Source code in fastack/mixins.py
def paginate(self, data: Sequence, page: int = 1, page_size: int = 10) -> Sequence:
    """
    Paginate data.

    Args:
        data: Data to be paginated.
        page: Page number.
        page_size: Page size.

    """

    if self.pagination_class:
        data = self.pagination_class(page, page_size).paginate(data)

    results = []
    for o in data:
        o = self.serialize_data(o)  # type: ignore[attr-defined]
        o = jsonable_encoder(o)
        results.append(o)

    return results

Last update: February 6, 2022 15:08:54