diff options
| author | Tom Christie | 2012-11-16 22:45:57 +0000 | 
|---|---|---|
| committer | Tom Christie | 2012-11-16 22:45:57 +0000 | 
| commit | 31f01bd6315f46bf28bb4c9c25a5298785fc4fc6 (patch) | |
| tree | 8f2c0ef593402a23118d71c7f81734c30ef5d2cc /rest_framework | |
| parent | 9973cf329a2133a900256b53236348ef3c870842 (diff) | |
| download | django-rest-framework-31f01bd6315f46bf28bb4c9c25a5298785fc4fc6.tar.bz2 | |
Polishing to page size query parameters & more docs
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/generics.py | 32 | ||||
| -rw-r--r-- | rest_framework/mixins.py | 13 | ||||
| -rw-r--r-- | rest_framework/settings.py | 9 | ||||
| -rw-r--r-- | rest_framework/tests/pagination.py | 85 | 
4 files changed, 43 insertions, 96 deletions
| diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 9ad03f71..dcf4dfd9 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -14,6 +14,7 @@ class GenericAPIView(views.APIView):      """      Base class for all other generic views.      """ +    model = None      serializer_class = None      model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS @@ -30,8 +31,10 @@ class GenericAPIView(views.APIView):      def get_serializer_class(self):          """          Return the class to use for the serializer. -        Use `self.serializer_class`, falling back to constructing a -        model serializer class from `self.model_serializer_class` + +        Defaults to using `self.serializer_class`, falls back to constructing a +        model serializer class using `self.model_serializer_class`, with +        `self.model` as the model.          """          serializer_class = self.serializer_class @@ -58,29 +61,42 @@ class MultipleObjectAPIView(MultipleObjectMixin, GenericAPIView):      pagination_serializer_class = api_settings.DEFAULT_PAGINATION_SERIALIZER_CLASS      paginate_by = api_settings.PAGINATE_BY +    paginate_by_param = api_settings.PAGINATE_BY_PARAM      filter_backend = api_settings.FILTER_BACKEND      def filter_queryset(self, queryset): +        """ +        Given a queryset, filter it with whichever filter backend is in use. +        """          if not self.filter_backend:              return queryset          backend = self.filter_backend()          return backend.filter_queryset(self.request, queryset, self) -    def get_pagination_serializer_class(self): +    def get_pagination_serializer(self, page=None):          """ -        Return the class to use for the pagination serializer. +        Return a serializer instance to use with paginated data.          """          class SerializerClass(self.pagination_serializer_class):              class Meta:                  object_serializer_class = self.get_serializer_class() -        return SerializerClass - -    def get_pagination_serializer(self, page=None): -        pagination_serializer_class = self.get_pagination_serializer_class() +        pagination_serializer_class = SerializerClass          context = self.get_serializer_context()          return pagination_serializer_class(instance=page, context=context) +    def get_paginate_by(self, queryset): +        """ +        Return the size of pages to use with pagination. +        """ +        if self.paginate_by_param: +            params = self.request.QUERY_PARAMS +            try: +                return int(params[self.paginate_by_param]) +            except (KeyError, ValueError): +                pass +        return self.paginate_by +  class SingleObjectAPIView(SingleObjectMixin, GenericAPIView):      """ diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 0da4c2cc..53c4d984 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -7,7 +7,6 @@ which allows mixin classes to be composed in interesting ways.  from django.http import Http404  from rest_framework import status  from rest_framework.response import Response -from rest_framework.settings import api_settings  class CreateModelMixin(object): @@ -40,7 +39,6 @@ class ListModelMixin(object):      Should be mixed in with `MultipleObjectAPIView`.      """      empty_error = u"Empty list and '%(class_name)s.allow_empty' is False." -    page_size_kwarg = api_settings.PAGE_SIZE_KWARG      def list(self, request, *args, **kwargs):          queryset = self.get_queryset() @@ -66,17 +64,6 @@ class ListModelMixin(object):          return Response(serializer.data) -    def get_paginate_by(self, queryset): -        if self.page_size_kwarg is not None: -            page_size_kwarg = self.request.QUERY_PARAMS.get(self.page_size_kwarg) -            if page_size_kwarg: -                try: -                    page_size = int(page_size_kwarg) -                    return page_size -                except ValueError: -                    pass -        return super(ListModelMixin, self).get_paginate_by(queryset) -  class RetrieveModelMixin(object):      """ diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 8883b963..ee24a4ad 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -54,12 +54,19 @@ DEFAULTS = {          'user': None,          'anon': None,      }, + +    # Pagination      'PAGINATE_BY': None, +    'PAGINATE_BY_PARAM': None, + +    # Filtering      'FILTER_BACKEND': None, +    # Authentication      'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',      'UNAUTHENTICATED_TOKEN': None, +    # Browser enhancements      'FORM_METHOD_OVERRIDE': '_method',      'FORM_CONTENT_OVERRIDE': '_content',      'FORM_CONTENTTYPE_OVERRIDE': '_content_type', @@ -67,8 +74,6 @@ DEFAULTS = {      'URL_FORMAT_OVERRIDE': 'format',      'FORMAT_SUFFIX_KWARG': 'format', - -    'PAGE_SIZE_KWARG': 'page_size'  } diff --git a/rest_framework/tests/pagination.py b/rest_framework/tests/pagination.py index 8aae2147..3062007d 100644 --- a/rest_framework/tests/pagination.py +++ b/rest_framework/tests/pagination.py @@ -36,25 +36,17 @@ if django_filters:  class DefaultPageSizeKwargView(generics.ListAPIView):      """ -    View for testing default page_size usage +    View for testing default paginate_by_param usage      """      model = BasicModel -class CustomPageSizeKwargView(generics.ListAPIView): +class PaginateByParamView(generics.ListAPIView):      """ -    View for testing custom page_size usage +    View for testing custom paginate_by_param usage      """      model = BasicModel -    page_size_kwarg = 'ps' - - -class NonePageSizeKwargView(generics.ListAPIView): -    """ -    View for testing None page_size usage -    """ -    model = BasicModel -    page_size_kwarg = None +    paginate_by_param = 'page_size'  class IntegrationTestPagination(TestCase): @@ -181,9 +173,9 @@ class UnitTestPagination(TestCase):          self.assertEquals(serializer.data['results'], self.objects[20:]) -class TestDefaultPageSizeKwarg(TestCase): +class TestUnpaginated(TestCase):      """ -    Tests for list views with default page size kwarg +    Tests for list views without pagination.      """      def setUp(self): @@ -199,26 +191,17 @@ class TestDefaultPageSizeKwarg(TestCase):          ]          self.view = DefaultPageSizeKwargView.as_view() -    def test_default_page_size(self): +    def test_unpaginated(self):          """          Tests the default page size for this view.          no page size --> no limit --> no meta data          """          request = factory.get('/') -        response = self.view(request).render() +        response = self.view(request)          self.assertEquals(response.data, self.data) -    def test_default_page_size_kwarg(self): -        """ -        If page_size_kwarg is set not set, the default page_size kwarg should limit per view requests. -        """ -        request = factory.get('/?page_size=5') -        response = self.view(request).render() -        self.assertEquals(response.data['count'], 13) -        self.assertEquals(response.data['results'], self.data[:5]) - -class TestCustomPageSizeKwarg(TestCase): +class TestCustomPaginateByParam(TestCase):      """      Tests for list views with default page size kwarg      """ @@ -234,7 +217,7 @@ class TestCustomPageSizeKwarg(TestCase):          {'id': obj.id, 'text': obj.text}          for obj in self.objects.all()          ] -        self.view = CustomPageSizeKwargView.as_view() +        self.view = PaginateByParamView.as_view()      def test_default_page_size(self):          """ @@ -245,55 +228,11 @@ class TestCustomPageSizeKwarg(TestCase):          response = self.view(request).render()          self.assertEquals(response.data, self.data) -    def test_disabled_default_page_size_kwarg(self): +    def test_paginate_by_param(self):          """ -        If page_size_kwarg is set set, the default page_size kwarg should not work. +        If paginate_by_param is set, the new kwarg should limit per view requests.          """          request = factory.get('/?page_size=5')          response = self.view(request).render() -        self.assertEquals(response.data, self.data) - -    def test_custom_page_size_kwarg(self): -        """ -        If page_size_kwarg is set set, the new kwarg should limit per view requests. -        """ -        request = factory.get('/?ps=5') -        response = self.view(request).render()          self.assertEquals(response.data['count'], 13)          self.assertEquals(response.data['results'], self.data[:5]) - - -class TestNonePageSizeKwarg(TestCase): -    """ -    Tests for list views with default page size kwarg -    """ - -    def setUp(self): -        """ -        Create 13 BasicModel instances. -        """ -        for i in range(13): -            BasicModel(text=i).save() -        self.objects = BasicModel.objects -        self.data = [ -        {'id': obj.id, 'text': obj.text} -        for obj in self.objects.all() -        ] -        self.view = NonePageSizeKwargView.as_view() - -    def test_default_page_size(self): -        """ -        Tests the default page size for this view. -        no page size --> no limit --> no meta data -        """ -        request = factory.get('/') -        response = self.view(request).render() -        self.assertEquals(response.data, self.data) - -    def test_none_page_size_kwarg(self): -        """ -        If page_size_kwarg is set to None, custom page_size per request should be disabled. -        """ -        request = factory.get('/?page_size=5') -        response = self.view(request).render() -        self.assertEquals(response.data, self.data) | 
