7π
1. Including Link
Header in response:
To include a Link
header in your response, you need to create a custom pagination serializer class, This should subclass pagination.BasePagination
and override the get_paginated_response(self, data)
method.
Example (taken from docs):
Suppose we want to replace the default pagination output style with a modified format that includes the next and previous links in a Link
header, we override the get_paginated_response()
.
class LinkHeaderPagination(pagination.PageNumberPagination):
def get_paginated_response(self, data):
next_url = self.get_next_link()
previous_url = self.get_previous_link()
if next_url is not None and previous_url is not None:
link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">'
elif next_url is not None:
link = '<{next_url}; rel="next">'
elif previous_url is not None:
link = '<{previous_url}; rel="prev">'
else:
link = ''
link = link.format(next_url=next_url, previous_url=previous_url)
headers = {'Link': link} if link else {}
return Response(data, headers=headers)
After this, we need to include this pagination class in our settings so that it is used by DRF instead of the default pagination classes.
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.LinkHeaderPagination',
'PAGE_SIZE': 100
}
API responses for list endpoints will now include a Link
header.
2. Including Content-Range
Header in response:
You can also send Content-Range
header instead of Link
. Just create a headers dictionary with Content-Range
as the key and value as how many items are being returned and how many total items exist.
For example:
class ContentRangeHeaderPagination(pagination.PageNumberPagination):
def get_paginated_response(self, data):
total_items = self.page.paginator.count
item_starting_index = self.page.start_index() - 1 # In a page, indexing starts from 1
item_ending_index = self.page.end_index() - 1
content_range = 'items {0}-{1}/{2}'.format(item_starting_index, item_ending_index, total_items)
headers = {'Content-Range': content_range}
return Response(data, headers=headers)
Suppose this is the header received:
Content-Range: items 0-9/50
This tells us that the response has a Content-Range
header with value as items 0-9/50
. This indicates that first 10 items are returned out of total 50
.
You can also use *
instead of total no. of items if calculating total is expensive.
Content-Range: items 0-9/* # Use this if total is expensive to calculate
0π
DRF recommends a thirdparty package in its documentation: django-rest-framework-link-header-pagination
It is supposed to follow the same path as the Github API, which is basically the proper way of doing what the other answer suggest.
Here is a sample Link header taken from Githubβs API guide:
Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev"
I havenβt tried the package yet but Iβll report back once done.
- [Django]-Django : Parsing Json data to template
- [Django]-Image is not uploaded via django form
- [Django]-Weird behavior of Django translation of one word in plural and singular form