Skip to content

Commit

Permalink
Move paginate_objects to PaginationMixin.
Browse files Browse the repository at this point in the history
  • Loading branch information
allisson committed Oct 31, 2015
1 parent cecc4f5 commit b242153
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 51 deletions.
7 changes: 3 additions & 4 deletions testproject/blog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@

from tiny_rest.views import APIView
from tiny_rest.authorization import IsAuthenticatedOrReadOnlyMixin
from tiny_rest.pagination import PaginationMixin
import status

from blog.models import Post, Comment, post_to_dict, comment_to_dict
from blog.forms import PostForm, CommentForm


class PostAPIView(IsAuthenticatedOrReadOnlyMixin, APIView):

paginate_by = 10
class PostAPIView(IsAuthenticatedOrReadOnlyMixin, PaginationMixin, APIView):

def get_post(self):
try:
Expand Down Expand Up @@ -100,7 +99,7 @@ def destroy(self, request, *args, **kwargs):
return self.response(data={}, status_code=status.HTTP_204_NO_CONTENT)


class CommentAPIView(IsAuthenticatedOrReadOnlyMixin, APIView):
class CommentAPIView(IsAuthenticatedOrReadOnlyMixin, PaginationMixin, APIView):

paginate_by = 10

Expand Down
55 changes: 55 additions & 0 deletions tiny_rest/pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from qurl import qurl


class PaginationMixin(object):

paginate_by = 10

def paginate_objects(self, request, objects):
paginator = Paginator(objects, self.paginate_by)
page = request.GET.get('page', 1)

try:
object_list = paginator.page(page)
except PageNotAnInteger:
object_list = paginator.page(1)
except EmptyPage:
object_list = paginator.page(paginator.num_pages)

pagination = {
'count': object_list.paginator.count,
'num_pages': object_list.paginator.num_pages,
'previous_page_number': None,
'previous_url': None,
'next_page_number': None,
'next_url': None
}
url = request.get_full_path()

if object_list.has_next():
next_page_number = object_list.next_page_number()
pagination['next_page_number'] = next_page_number
pagination['next_url'] = 'http://{0}{1}'.format(
request.get_host(),
qurl(
url,
add={'page': object_list.next_page_number()}
)
)

if object_list.has_previous():
previous_page_number = object_list.previous_page_number()
pagination['previous_page_number'] = previous_page_number
pagination['previous_url'] = 'http://{0}{1}'.format(
request.get_host(),
qurl(
url,
add={'page': object_list.previous_page_number()}
)
)

return object_list, pagination
61 changes: 61 additions & 0 deletions tiny_rest/tests/test_pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase, RequestFactory
from django.contrib.auth.models import AnonymousUser

import json
import status

from tiny_rest.views import APIView
from tiny_rest.pagination import PaginationMixin


class PaginationAPIView(PaginationMixin, APIView):

paginate_by = 5

def list(self, request, *args, **kwargs):
objects = range(10)
object_list, pagination = self.paginate_objects(request, objects)
data = {
'pagination': pagination,
'data': [number for number in object_list]
}
return self.response(data=data)


class TestPaginationAPIView(TestCase):

def setUp(self):
self.factory = RequestFactory()

def test_paginate_objects(self):
request = self.factory.get('/')
request.user = AnonymousUser()
response = PaginationAPIView.as_view()(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = json.loads(response.content.decode())
self.assertEqual(data['pagination']['count'], 10)
self.assertEqual(data['pagination']['num_pages'], 2)
self.assertFalse(data['pagination']['previous_page_number'])
self.assertFalse(data['pagination']['previous_url'])
self.assertEqual(data['pagination']['next_page_number'], 2)
self.assertEqual(
data['pagination']['next_url'], 'http://testserver/?page=2'
)
self.assertEqual(data['data'], [0, 1, 2, 3, 4])

request = self.factory.get('/?page=2')
request.user = AnonymousUser()
response = PaginationAPIView.as_view()(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = json.loads(response.content.decode())
self.assertEqual(data['pagination']['count'], 10)
self.assertEqual(data['pagination']['num_pages'], 2)
self.assertEqual(data['pagination']['previous_page_number'], 1)
self.assertEqual(
data['pagination']['previous_url'], 'http://testserver/?page=1'
)
self.assertFalse(data['pagination']['next_page_number'])
self.assertFalse(data['pagination']['next_url'])
self.assertEqual(data['data'], [5, 6, 7, 8, 9])
47 changes: 0 additions & 47 deletions tiny_rest/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.views.generic import View
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import AnonymousUser

from qurl import qurl
import status

from tiny_rest.http import JsonResponse
Expand Down Expand Up @@ -51,51 +49,6 @@ def authenticate(self, request):
def authorize(self, request):
return True

def paginate_objects(self, request, objects):
paginator = Paginator(objects, self.paginate_by)
page = request.GET.get('page', 1)

try:
object_list = paginator.page(page)
except PageNotAnInteger:
object_list = paginator.page(1)
except EmptyPage:
object_list = paginator.page(paginator.num_pages)

pagination = {
'count': object_list.paginator.count,
'num_pages': object_list.paginator.num_pages,
'previous_page_number': None,
'previous_url': None,
'next_page_number': None,
'next_url': None
}
url = request.get_full_path()

if object_list.has_next():
next_page_number = object_list.next_page_number()
pagination['next_page_number'] = next_page_number
pagination['next_url'] = 'http://{0}{1}'.format(
request.get_host(),
qurl(
url,
add={'page': object_list.next_page_number()}
)
)

if object_list.has_previous():
previous_page_number = object_list.previous_page_number()
pagination['previous_page_number'] = previous_page_number
pagination['previous_url'] = 'http://{0}{1}'.format(
request.get_host(),
qurl(
url,
add={'page': object_list.previous_page_number()}
)
)

return object_list, pagination

def get(self, request, *args, **kwargs):
if self.pk:
return self.detail(request, *args, **kwargs)
Expand Down

0 comments on commit b242153

Please sign in to comment.