Expose page_size in paginated API response

Fix #4837
This commit is contained in:
Mathieu Pillard 2017-03-03 18:43:04 +01:00
Родитель c2f77248d6
Коммит ccd830913a
3 изменённых файлов: 65 добавлений и 3 удалений

Просмотреть файл

@ -72,6 +72,7 @@ following properties will be available in the responses of those endpoints:
* *next*: the URL for the next page in the pagination.
* *previous*: the URL for the previous page in the pagination.
* *page_size*: The number of items per page in the pagination.
* *count*: the total number of records.
* *results*: the array containing the results for this page.

Просмотреть файл

@ -1,4 +1,8 @@
from collections import OrderedDict
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from django.core.paginator import (
EmptyPage, InvalidPage, Page, PageNotAnInteger, Paginator)
@ -68,6 +72,19 @@ class CustomPageNumberPagination(PageNumberPagination):
page_size_query_param = 'page_size'
max_page_size = 50
def get_paginated_response(self, data):
# Like PageNumberPagination.get_paginated_response, but with
# 'page_size' added to the top of the response data.
return Response(OrderedDict([
# Note that self.page_size doesn't work, it contains the default
# page size.
('page_size', self.page.paginator.per_page),
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
class ESPageNumberPagination(CustomPageNumberPagination):
"""Custom pagination implementation to hook in our `ESPaginator`."""

Просмотреть файл

@ -1,9 +1,15 @@
from django.core.paginator import EmptyPage, InvalidPage, PageNotAnInteger
from mock import MagicMock
from django.core.paginator import EmptyPage, InvalidPage, PageNotAnInteger
from rest_framework import generics
from rest_framework import serializers
from rest_framework import status
from rest_framework.test import APIRequestFactory
from olympia.amo.tests import TestCase
from olympia.api.paginator import ESPaginator, Paginator
from olympia.api.paginator import (
CustomPageNumberPagination, ESPaginator, Paginator)
class TestSearchPaginator(TestCase):
@ -41,3 +47,41 @@ class TestSearchPaginator(TestCase):
with self.assertRaises(PageNotAnInteger):
paginator.page('lol')
class TestCustomPageNumberPagination(TestCase):
def setUp(self):
class PassThroughSerializer(serializers.BaseSerializer):
def to_representation(self, item):
return item
self.factory = APIRequestFactory()
self.view = generics.ListAPIView.as_view(
serializer_class=PassThroughSerializer,
queryset=range(1, 101),
pagination_class=CustomPageNumberPagination
)
def test_metadata_with_page_size(self):
request = self.factory.get('/', {'page_size': 10, 'page': 2})
response = self.view(request)
assert response.status_code == status.HTTP_200_OK
assert response.data == {
'page_size': 10,
'results': range(11, 21),
'previous': 'http://testserver/?page_size=10',
'next': 'http://testserver/?page=3&page_size=10',
'count': 100
}
def test_metadata_with_default_page_size(self):
request = self.factory.get('/')
response = self.view(request)
assert response.status_code == status.HTTP_200_OK
assert response.data == {
'page_size': 25,
'results': range(1, 26),
'previous': None,
'next': 'http://testserver/?page=2',
'count': 100
}