Skip to content

Commit c927065

Browse files
committed
added custom pagination
1 parent 8475220 commit c927065

File tree

2 files changed

+74
-29
lines changed

2 files changed

+74
-29
lines changed

django_petra/paginate.py

+39-29
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,45 @@
1-
from rest_framework.response import Response
2-
from rest_framework.pagination import PageNumberPagination
31
from collections import OrderedDict
2+
from math import ceil
3+
from django.core.paginator import Paginator
4+
from rest_framework.response import Response
5+
from urllib.parse import urlparse
6+
7+
def paginate(request, queryset, serializer_class, per_page=10, wrap='data', additional_data=None):
8+
# Get per_page from query params if present, otherwise use default
9+
per_page = int(request.query_params.get('per_page', per_page))
10+
page = int(request.query_params.get('page', 1))
11+
total = queryset.count()
12+
last_page = ceil(total / per_page)
13+
offset = (page - 1) * per_page
14+
15+
paginated_queryset = queryset[offset:offset + per_page]
16+
serializer = serializer_class(paginated_queryset, many=True)
17+
data = serializer.data
418

5-
class LaravelStylePagination(PageNumberPagination):
6-
page_size = 10
7-
8-
def get_paginated_response(self, data, wrap):
9-
data = (OrderedDict([
10-
('per_page', self.page_size),
11-
('current_page', self.page.number),
12-
('last_page', self.page.paginator.num_pages),
13-
('next_page_url', self.get_next_link() or None),
14-
('prev_page_url', self.get_previous_link() or None),
15-
('total', self.page.paginator.count),
16-
('from', self.page.start_index()),
17-
('to', self.page.end_index()),
18-
(wrap, data),
19-
]))
20-
return data
19+
full_path = str(request.build_absolute_uri())
20+
parsed_url = urlparse(full_path)
21+
path_without_query = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"
2122

22-
23-
def paginate(request, queryset, serializer_class, per_page=2, wrap='data'):
24-
# Create an instance of the custom pagination class
25-
paginator = LaravelStylePagination()
26-
paginator.page_size = per_page
23+
first_page_url = f"{path_without_query}?page=1&per_page={per_page}"
24+
last_page_url = f"{path_without_query}?page={last_page}&per_page={per_page}"
25+
next_page_url = f"{path_without_query}?page={page + 1}&per_page={per_page}" if page < last_page else None
26+
prev_page_url = f"{path_without_query}?page={page - 1}&per_page={per_page}" if page > 1 else None
2727

28-
# Paginate the queryset
29-
page = paginator.paginate_queryset(queryset, request)
28+
# Convert all URLs to strings explicitly
29+
response_data = OrderedDict([
30+
(wrap, data),
31+
('total', total),
32+
('per_page', int(per_page)), # ensure integer
33+
('current_page', int(page)), # ensure integer
34+
('last_page', int(last_page)), # ensure integer
35+
('first_page_url', str(first_page_url)),
36+
('last_page_url', str(last_page_url)),
37+
('next_page_url', str(next_page_url) if next_page_url else None),
38+
('prev_page_url', str(prev_page_url) if prev_page_url else None),
39+
])
3040

31-
# Serialize the paginated data using the provided serializer class
32-
serializer = serializer_class(page, many=True)
41+
# Merge additional_data if provided
42+
if additional_data:
43+
response_data['additional_data'] = additional_data
3344

34-
# Return the paginated data along with pagination metadata
35-
return paginator.get_paginated_response(serializer.data, wrap)
45+
return response_data

django_petra/paginate_old.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from rest_framework.response import Response
2+
from rest_framework.pagination import PageNumberPagination
3+
from collections import OrderedDict
4+
5+
class LaravelStylePagination(PageNumberPagination):
6+
page_size = 10
7+
8+
def get_paginated_response(self, data, wrap):
9+
data = (OrderedDict([
10+
('per_page', self.page_size),
11+
('current_page', self.page.number),
12+
('last_page', self.page.paginator.num_pages),
13+
('next_page_url', self.get_next_link() or None),
14+
('prev_page_url', self.get_previous_link() or None),
15+
('total', self.page.paginator.count),
16+
('from', self.page.start_index()),
17+
('to', self.page.end_index()),
18+
(wrap, data),
19+
]))
20+
return data
21+
22+
23+
def paginate(request, queryset, serializer_class, per_page=2, wrap='data'):
24+
# Create an instance of the custom pagination class
25+
paginator = LaravelStylePagination()
26+
paginator.page_size = per_page
27+
28+
# Paginate the queryset
29+
page = paginator.paginate_queryset(queryset, request)
30+
31+
# Serialize the paginated data using the provided serializer class
32+
serializer = serializer_class(page, many=True)
33+
34+
# Return the paginated data along with pagination metadata
35+
return paginator.get_paginated_response(serializer.data, wrap)

0 commit comments

Comments
 (0)