aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2015-03-04 15:51:00 +0000
committerTom Christie2015-03-04 15:51:00 +0000
commit18cc0230bff436da2f26b2b25034cece32c9f5d0 (patch)
treef5648574b0d80b8d4b236d05110c59cc5d54eda6
parent5aa204e94f3173e8bc20439033a5d613625b1311 (diff)
downloaddjango-rest-framework-18cc0230bff436da2f26b2b25034cece32c9f5d0.tar.bz2
Clean up pagination attributes
-rwxr-xr-xdocs/api-guide/generic-views.md7
-rw-r--r--docs/tutorial/5-relationships-and-hyperlinked-apis.md2
-rw-r--r--docs/tutorial/quickstart.md2
-rw-r--r--rest_framework/pagination.py73
-rw-r--r--rest_framework/settings.py11
-rw-r--r--tests/test_pagination.py8
6 files changed, 71 insertions, 32 deletions
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 61c8e8d8..39e09aaa 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -84,10 +84,9 @@ The following attributes control the basic view behavior.
The following attributes are used to control pagination when used with list views.
-* `paginate_by` - The size of pages to use with paginated data. If set to `None` then pagination is turned off. If unset this uses the same value as the `PAGINATE_BY` setting, which defaults to `None`.
-* `paginate_by_param` - The name of a query parameter, which can be used by the client to override the default page size to use for pagination. If unset this uses the same value as the `PAGINATE_BY_PARAM` setting, which defaults to `None`.
-* `pagination_serializer_class` - The pagination serializer class to use when determining the style of paginated responses. Defaults to the same value as the `DEFAULT_PAGINATION_SERIALIZER_CLASS` setting.
-* `page_kwarg` - The name of a URL kwarg or URL query parameter which can be used by the client to control which page is requested. Defaults to `'page'`.
+* `pagination_class` - The pagination class that should be used when paginating list results. Defaults to the same value as the `DEFAULT_PAGINATION_CLASS` setting, which is `'rest_framework.pagination.PageNumberPagination'`.
+
+Note that usage of the `paginate_by`, `paginate_by_param` and `page_kwarg` attributes are now pending deprecation. The `pagination_serializer_class` attribute and `DEFAULT_PAGINATION_SERIALIZER_CLASS` setting have been removed completely. Pagination settings should instead be controlled by overriding a pagination class and setting any configuration attributes there. See the pagination documentation for more details.
**Filtering**:
diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md
index 740a4ce2..91cdd6f1 100644
--- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md
+++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md
@@ -141,7 +141,7 @@ The list views for users and code snippets could end up returning quite a lot of
We can change the default list style to use pagination, by modifying our `tutorial/settings.py` file slightly. Add the following setting:
REST_FRAMEWORK = {
- 'PAGINATE_BY': 10
+ 'PAGE_SIZE': 10
}
Note that settings in REST framework are all namespaced into a single dictionary setting, named 'REST_FRAMEWORK', which helps keep them well separated from your other project settings.
diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md
index a4474c34..fe0ecbc7 100644
--- a/docs/tutorial/quickstart.md
+++ b/docs/tutorial/quickstart.md
@@ -123,7 +123,7 @@ We'd also like to set a few global settings. We'd like to turn on pagination, a
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
- 'PAGINATE_BY': 10
+ 'PAGE_SIZE': 10
}
Okay, we're done.
diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py
index 80985873..6a2f5b27 100644
--- a/rest_framework/pagination.py
+++ b/rest_framework/pagination.py
@@ -18,6 +18,7 @@ from rest_framework.settings import api_settings
from rest_framework.utils.urls import (
replace_query_param, remove_query_param
)
+import warnings
def _positive_int(integer_string, strict=False, cutoff=None):
@@ -203,18 +204,18 @@ class PageNumberPagination(BasePagination):
"""
# The default page size.
# Defaults to `None`, meaning pagination is disabled.
- paginate_by = api_settings.PAGINATE_BY
+ page_size = api_settings.PAGE_SIZE
# Client can control the page using this query parameter.
page_query_param = 'page'
# Client can control the page size using this query parameter.
# Default is 'None'. Set to eg 'page_size' to enable usage.
- paginate_by_param = api_settings.PAGINATE_BY_PARAM
+ page_size_query_param = None
# Set to an integer to limit the maximum page size the client may request.
- # Only relevant if 'paginate_by_param' has also been set.
- max_paginate_by = api_settings.MAX_PAGINATE_BY
+ # Only relevant if 'page_size_query_param' has also been set.
+ max_page_size = None
last_page_strings = ('last',)
@@ -228,12 +229,48 @@ class PageNumberPagination(BasePagination):
attributes were set there. The attributes should now be set on
the pagination class, but the old style is still pending deprecation.
"""
- for attr in (
- 'paginate_by', 'page_query_param',
- 'paginate_by_param', 'max_paginate_by'
+ assert not (
+ getattr(view, 'pagination_serializer_class', None) or
+ getattr(api_settings, 'DEFAULT_PAGINATION_SERIALIZER_CLASS', None)
+ ), (
+ "The pagination_serializer_class attribute and "
+ "DEFAULT_PAGINATION_SERIALIZER_CLASS setting have been removed as "
+ "part of the 3.1 pagination API improvement. See the pagination "
+ "documentation for details on the new API."
+ )
+
+ for (settings_key, attr_name) in (
+ ('PAGINATE_BY', 'page_size'),
+ ('PAGINATE_BY_PARAM', 'page_size_query_param'),
+ ('MAX_PAGINATE_BY', 'max_page_size')
):
- if hasattr(view, attr):
- setattr(self, attr, getattr(view, attr))
+ value = getattr(api_settings, settings_key, None)
+ if value is not None:
+ setattr(self, attr_name, value)
+ warnings.warn(
+ "The `%s` settings key is pending deprecation. "
+ "Use the `%s` attribute on the pagination class instead." % (
+ settings_key, attr_name
+ ),
+ PendingDeprecationWarning,
+ )
+
+ for (view_attr, attr_name) in (
+ ('paginate_by', 'page_size'),
+ ('page_query_param', 'page_query_param'),
+ ('paginate_by_param', 'page_size_query_param'),
+ ('max_paginate_by', 'max_page_size')
+ ):
+ value = getattr(view, view_attr, None)
+ if value is not None:
+ setattr(self, attr_name, value)
+ warnings.warn(
+ "The `%s` view attribute is pending deprecation. "
+ "Use the `%s` attribute on the pagination class instead." % (
+ view_attr, attr_name
+ ),
+ PendingDeprecationWarning,
+ )
def paginate_queryset(self, queryset, request, view=None):
"""
@@ -264,7 +301,7 @@ class PageNumberPagination(BasePagination):
self.display_page_controls = True
self.request = request
- return self.page
+ return list(self.page)
def get_paginated_response(self, data):
return Response(OrderedDict([
@@ -275,17 +312,17 @@ class PageNumberPagination(BasePagination):
]))
def get_page_size(self, request):
- if self.paginate_by_param:
+ if self.page_size_query_param:
try:
return _positive_int(
- request.query_params[self.paginate_by_param],
+ request.query_params[self.page_size_query_param],
strict=True,
- cutoff=self.max_paginate_by
+ cutoff=self.max_page_size
)
except (KeyError, ValueError):
pass
- return self.paginate_by
+ return self.page_size
def get_next_link(self):
if not self.page.has_next():
@@ -336,7 +373,7 @@ class LimitOffsetPagination(BasePagination):
http://api.example.org/accounts/?limit=100
http://api.example.org/accounts/?offset=400&limit=100
"""
- default_limit = api_settings.PAGINATE_BY
+ default_limit = api_settings.PAGE_SIZE
limit_query_param = 'limit'
offset_query_param = 'offset'
max_limit = None
@@ -349,7 +386,7 @@ class LimitOffsetPagination(BasePagination):
self.request = request
if self.count > self.limit and self.template is not None:
self.display_page_controls = True
- return queryset[self.offset:self.offset + self.limit]
+ return list(queryset[self.offset:self.offset + self.limit])
def get_paginated_response(self, data):
return Response(OrderedDict([
@@ -440,7 +477,7 @@ class CursorPagination(BasePagination):
# Consider a max offset cap.
# Tidy up the `get_ordering` API (eg remove queryset from it)
cursor_query_param = 'cursor'
- page_size = api_settings.PAGINATE_BY
+ page_size = api_settings.PAGE_SIZE
invalid_cursor_message = _('Invalid cursor')
ordering = None
template = 'rest_framework/pagination/previous_and_next.html'
@@ -484,7 +521,7 @@ class CursorPagination(BasePagination):
# We also always fetch an extra item in order to determine if there is a
# page following on from this one.
results = list(queryset[offset:offset + self.page_size + 1])
- self.page = results[:self.page_size]
+ self.page = list(results[:self.page_size])
# Determine the position of the final item following the page.
if len(results) > len(self.page):
diff --git a/rest_framework/settings.py b/rest_framework/settings.py
index 394b1262..a3e9f590 100644
--- a/rest_framework/settings.py
+++ b/rest_framework/settings.py
@@ -61,9 +61,7 @@ DEFAULTS = {
'NUM_PROXIES': None,
# Pagination
- 'PAGINATE_BY': None,
- 'PAGINATE_BY_PARAM': None,
- 'MAX_PAGINATE_BY': None,
+ 'PAGE_SIZE': None,
# Filtering
'SEARCH_PARAM': 'search',
@@ -117,7 +115,12 @@ DEFAULTS = {
'UNICODE_JSON': True,
'COMPACT_JSON': True,
'COERCE_DECIMAL_TO_STRING': True,
- 'UPLOADED_FILES_USE_URL': True
+ 'UPLOADED_FILES_USE_URL': True,
+
+ # Pending deprecation:
+ 'PAGINATE_BY': None,
+ 'PAGINATE_BY_PARAM': None,
+ 'MAX_PAGINATE_BY': None
}
diff --git a/tests/test_pagination.py b/tests/test_pagination.py
index 13bfb627..6b39a6f2 100644
--- a/tests/test_pagination.py
+++ b/tests/test_pagination.py
@@ -24,9 +24,9 @@ class TestPaginationIntegration:
return [item for item in queryset if item % 2 == 0]
class BasicPagination(pagination.PageNumberPagination):
- paginate_by = 5
- paginate_by_param = 'page_size'
- max_paginate_by = 20
+ page_size = 5
+ page_size_query_param = 'page_size'
+ max_page_size = 20
self.view = generics.ListAPIView.as_view(
serializer_class=PassThroughSerializer,
@@ -185,7 +185,7 @@ class TestPageNumberPagination:
def setup(self):
class ExamplePagination(pagination.PageNumberPagination):
- paginate_by = 5
+ page_size = 5
self.pagination = ExamplePagination()
self.queryset = range(1, 101)