diff options
| author | Tom Christie | 2015-03-04 15:51:00 +0000 | 
|---|---|---|
| committer | Tom Christie | 2015-03-04 15:51:00 +0000 | 
| commit | 18cc0230bff436da2f26b2b25034cece32c9f5d0 (patch) | |
| tree | f5648574b0d80b8d4b236d05110c59cc5d54eda6 | |
| parent | 5aa204e94f3173e8bc20439033a5d613625b1311 (diff) | |
| download | django-rest-framework-18cc0230bff436da2f26b2b25034cece32c9f5d0.tar.bz2 | |
Clean up pagination attributes
| -rwxr-xr-x | docs/api-guide/generic-views.md | 7 | ||||
| -rw-r--r-- | docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 | ||||
| -rw-r--r-- | docs/tutorial/quickstart.md | 2 | ||||
| -rw-r--r-- | rest_framework/pagination.py | 73 | ||||
| -rw-r--r-- | rest_framework/settings.py | 11 | ||||
| -rw-r--r-- | tests/test_pagination.py | 8 | 
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) | 
