pagination.py 2.65 KB
Newer Older
1 2 3
"""
Discussion API pagination support
"""
4
from rest_framework.utils.urls import replace_query_param
5

6
from openedx.core.lib.api.paginators import NamespacedPageNumberPagination
7 8 9 10 11 12 13


class _Page(object):
    """
    Implements just enough of the django.core.paginator.Page interface to allow
    PaginationSerializer to work.
    """
14
    def __init__(self, page_num, num_pages):
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
        """
        Create a new page containing the given objects, with the given page
        number and number of pages
        """
        self.page_num = page_num
        self.num_pages = num_pages

    def has_next(self):
        """Returns True if there is a page after this one, otherwise False"""
        return self.page_num < self.num_pages

    def has_previous(self):
        """Returns True if there is a page before this one, otherwise False"""
        return self.page_num > 1

    def next_page_number(self):
        """Returns the number of the next page"""
        return self.page_num + 1

    def previous_page_number(self):
        """Returns the number of the previous page"""
        return self.page_num - 1


39
class DiscussionAPIPagination(NamespacedPageNumberPagination):
40
    """
41 42
    Subclasses NamespacedPageNumberPagination to provide custom implementation of pagination metadata
    by overriding it's methods
43
    """
44
    def __init__(self, request, page_num, num_pages, result_count=0):
45 46 47 48 49 50
        """
        Overrides parent constructor to take information from discussion api
        essential for the parent method
        """
        self.page = _Page(page_num, num_pages)
        self.base_url = request.build_absolute_uri()
51
        self.count = result_count
52 53 54 55 56

        super(DiscussionAPIPagination, self).__init__()

    def get_result_count(self):
        """
57
        Returns total number of results
58
        """
59
        return self.count
60

61 62 63 64
    def get_num_pages(self):
        """
        Returns total number of pages the response is divided into
        """
65
        return self.page.num_pages
66

67 68 69 70 71 72 73 74 75
    def get_next_link(self):
        """
        Returns absolute url of the next page if there's a next page available
        otherwise returns None
        """
        next_url = None
        if self.page.has_next():
            next_url = replace_query_param(self.base_url, "page", self.page.next_page_number())
        return next_url
76

77 78 79 80 81 82 83 84 85
    def get_previous_link(self):
        """
        Returns absolute url of the previous page if there's a previous page available
        otherwise returns None
        """
        previous_url = None
        if self.page.has_previous():
            previous_url = replace_query_param(self.base_url, "page", self.page.previous_page_number())
        return previous_url