From 80ad757337da749c9468805b2fce22e566e2a0bf Mon Sep 17 00:00:00 2001 From: Jean-Baptiste <bleme@pm.me> Date: Tue, 6 Aug 2019 11:09:12 +0200 Subject: [PATCH] update: use Link Headers for pagination --- README.md | 2 +- djangoldp/pagination.py | 16 ++++++++++++++++ djangoldp/tests/runner.py | 5 +++++ djangoldp/tests/tests_pagination.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 djangoldp/pagination.py create mode 100644 djangoldp/tests/tests_pagination.py diff --git a/README.md b/README.md index 80c0079b..433aa0a3 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ To enable pagination feature just add this configuration to the server `settings ``` REST_FRAMEWORK = { - 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', + 'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination', 'PAGE_SIZE': 20 } ``` diff --git a/djangoldp/pagination.py b/djangoldp/pagination.py new file mode 100644 index 00000000..90386d27 --- /dev/null +++ b/djangoldp/pagination.py @@ -0,0 +1,16 @@ +from rest_framework.pagination import LimitOffsetPagination +from rest_framework.response import Response + + +class LDPPagination(LimitOffsetPagination): + def get_paginated_response(self, data): + next_url = self.get_next_link() + previous_url = self.get_previous_link() + + links = [] + for url, label in ((previous_url, 'prev'), (next_url, 'next')): + if url is not None: + links.append('<{}>; rel="{}"'.format(url, label)) + + headers = {'Link': ', '.join(links)} if links else {} + return Response(data, headers=headers) diff --git a/djangoldp/tests/runner.py b/djangoldp/tests/runner.py index 86c7a99b..2dd377fa 100644 --- a/djangoldp/tests/runner.py +++ b/djangoldp/tests/runner.py @@ -49,6 +49,10 @@ settings.configure(DEBUG=False, 'djangoldp.tests', ), SITE_URL='http://happy-dev.fr', + REST_FRAMEWORK = { + 'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination', + 'PAGE_SIZE': 5 + }, ) django.setup() @@ -66,6 +70,7 @@ failures = test_runner.run_tests([ 'djangoldp.tests.tests_get', 'djangoldp.tests.tests_delete', 'djangoldp.tests.tests_sources', + 'djangoldp.tests.tests_pagination', # 'djangoldp.tests.tests_temp' ]) diff --git a/djangoldp/tests/tests_pagination.py b/djangoldp/tests/tests_pagination.py new file mode 100644 index 00000000..8e0cf5de --- /dev/null +++ b/djangoldp/tests/tests_pagination.py @@ -0,0 +1,28 @@ +from rest_framework.test import APIRequestFactory, APIClient, APITestCase + +from djangoldp.tests.models import Post + + +class TestPagination(APITestCase): + + def setUp(self): + self.factory = APIRequestFactory() + self.client = APIClient() + for i in range(0, 10): + Post.objects.create(content="content {}".format(i)) + + def tearDown(self): + pass + + def test_next(self): + response = self.client.get('/posts/', content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertIn('link', response._headers) + self.assertEquals(response._headers['link'][1], '<http://testserver/posts/?limit=5&offset=5>; rel="next"') + + def test_previous(self): + response = self.client.get('/posts/?offset=2&limit=2', content_type='application/ld+json') + self.assertEqual(response.status_code, 200) + self.assertIn('link', response._headers) + self.assertEquals(response._headers['link'][1], + '<http://testserver/posts/?limit=2>; rel="prev", <http://testserver/posts/?limit=2&offset=4>; rel="next"') -- GitLab