From 313aa727e3c44016e531a7af75051fc6e6d7cb96 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 14 Jan 2015 17:46:41 +0000 Subject: [PATCH] Tweaks --- docs/api-guide/pagination.md | 19 +++++++++++++++---- docs/img/link-header-pagination.png | Bin 0 -> 35799 bytes rest_framework/pagination.py | 12 ++++++++++-- 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 docs/img/link-header-pagination.png diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index 9fbeb22a0..ba71a3032 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -74,7 +74,7 @@ Note that the `paginate_queryset` method may set state on the pagination instanc Let's modify the built-in `PageNumberPagination` style, so that instead of include the pagination links in the body of the response, we'll instead include a `Link` header, in a [similar style to the GitHub API][github-link-pagination]. - class LinkHeaderPagination(PageNumberPagination) + class LinkHeaderPagination(pagination.PageNumberPagination): def get_paginated_response(self, data): next_url = self.get_next_link() previous_url = self.get_previous_link() @@ -82,7 +82,7 @@ Let's modify the built-in `PageNumberPagination` style, so that instead of inclu link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">' elif next_url is not None: link = '<{next_url}; rel="next">' - elif prev_url is not None: + elif previous_url is not None: link = '<{previous_url}; rel="prev">' else: link = '' @@ -97,10 +97,20 @@ Let's modify the built-in `PageNumberPagination` style, so that instead of inclu To have your custom pagination class be used by default, use the `DEFAULT_PAGINATION_CLASS` setting: REST_FRAMEWORK = { - 'DEFAULT_PAGINATION_CLASS': - 'my_project.apps.core.pagination.LinkHeaderPagination', + 'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.LinkHeaderPagination', + 'PAGINATE_BY': 10 } +API responses for list endpoints will now include a `Link` header, instead of including the pagination links as part of the body of the response, for example: + +--- + +![Link Header][link-header] + +*A custom pagination style, using the 'Link' header'* + +--- + # Third party packages The following third party packages are also available. @@ -111,5 +121,6 @@ The [`DRF-extensions` package][drf-extensions] includes a [`PaginateByMaxMixin` [cite]: https://docs.djangoproject.com/en/dev/topics/pagination/ [github-link-pagination]: https://developer.github.com/guides/traversing-with-pagination/ +[link-header]: ../img/link-header-pagination.png [drf-extensions]: http://chibisov.github.io/drf-extensions/docs/ [paginate-by-max-mixin]: http://chibisov.github.io/drf-extensions/docs/#paginatebymaxmixin diff --git a/docs/img/link-header-pagination.png b/docs/img/link-header-pagination.png new file mode 100644 index 0000000000000000000000000000000000000000..d3c556a4d6aebc3dc1575c43eced4059d864bab2 GIT binary patch literal 35799 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

FdM1>*;W0Ix=Z$X}_;J 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 Hu0mjfzM=e` literal 0 HcmV?d00001 diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index bd343c0dd..69d0f77d3 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -46,6 +46,12 @@ def _get_displayed_page_numbers(current, final): For example: current=14, final=16 -> [1, None, 13, 14, 15, 16] + + This implementation gives one page to each side of the cursor, + for an implementation which gives two pages to each side of the cursor, + which is a copy of how GitHub treat pagination in their issue lists, see: + + https://gist.github.com/tomchristie/321140cebb1c4a558b15 """ assert current >= 1 assert final >= current @@ -60,10 +66,12 @@ def _get_displayed_page_numbers(current, final): # If the break would only exclude a single page number then we # may as well include the page number instead of the break. - if current == 4: + if current <= 4: included.add(2) - if current == final - 3: + included.add(3) + if current >= final - 3: included.add(final - 1) + included.add(final - 2) # Now sort the page numbers and drop anything outside the limits. included = [