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) |
