mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-06 21:40:13 +03:00
Improved on LinkHeaderPagination example
- Fixes Link header syntax, which if I understand [RFC5988](http://www.rfc-editor.org/rfc/rfc5988.txt) correctly, was incorrect - Adds first and last page `<link>`s as and `X-Total-Count` as per http://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api - Adds `X-Total-Count` as per http://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api - Adds imports and python codeblock for easy reading
This commit is contained in:
parent
ad32e14360
commit
72b4310129
|
@ -51,7 +51,8 @@ You can then apply your new style to a view using the `.pagination_class` attrib
|
||||||
Or apply the style globally, using the `DEFAULT_PAGINATION_CLASS` settings key. For example:
|
Or apply the style globally, using the `DEFAULT_PAGINATION_CLASS` settings key. For example:
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
}
|
'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
|
||||||
|
}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -84,24 +85,45 @@ 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].
|
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].
|
||||||
|
|
||||||
|
```py
|
||||||
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.utils.urls import remove_query_param, replace_query_param
|
||||||
|
|
||||||
|
|
||||||
class LinkHeaderPagination(pagination.PageNumberPagination):
|
class LinkHeaderPagination(pagination.PageNumberPagination):
|
||||||
def get_paginated_response(self, data):
|
def get_paginated_response(self, data):
|
||||||
next_url = self.get_next_link()
previous_url = self.get_previous_link()
|
link = '<{}>; rel="{}"'
|
||||||
|
|
||||||
if next_url is not None and previous_url is not None:
|
first = self.get_first_link()
|
||||||
link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">'
|
prev = self.get_previous_link()
|
||||||
elif next_url is not None:
|
next = self.get_next_link()
|
||||||
link = '<{next_url}; rel="next">'
|
last = self.get_last_link()
|
||||||
elif previous_url is not None:
|
|
||||||
link = '<{previous_url}; rel="prev">'
|
|
||||||
else:
|
|
||||||
link = ''
|
|
||||||
|
|
||||||
link = link.format(next_url=next_url, previous_url=previous_url)
|
links = [
|
||||||
headers = {'Link': link} if link else {}
|
link.format(first, 'first'),
|
||||||
|
link.format(prev, 'prev') if prev else None,
|
||||||
|
link.format(next, 'next') if next else None,
|
||||||
|
link.format(last, 'last'),
|
||||||
|
]
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'Link': ", ".join([link for link in links if link]),
|
||||||
|
'X-Total-Count': self.page.paginator.count
|
||||||
|
}
|
||||||
|
|
||||||
return Response(data, headers=headers)
|
return Response(data, headers=headers)
|
||||||
|
|
||||||
|
def get_first_link(self):
|
||||||
|
url = self.request.build_absolute_uri()
|
||||||
|
return remove_query_param(url, self.page_query_param)
|
||||||
|
|
||||||
|
def get_last_link(self):
|
||||||
|
url = self.request.build_absolute_uri()
|
||||||
|
page_number = self.page.paginator.num_pages
|
||||||
|
return replace_query_param(url, self.page_query_param, page_number)
|
||||||
|
```
|
||||||
|
|
||||||
## Using your custom pagination class
|
## Using your custom pagination class
|
||||||
|
|
||||||
To have your custom pagination class be used by default, use the `DEFAULT_PAGINATION_CLASS` setting:
|
To have your custom pagination class be used by default, use the `DEFAULT_PAGINATION_CLASS` setting:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user