mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-02 19:40:13 +03:00
Add LinkPagination support
This commit is contained in:
parent
a500b83ff2
commit
bf227649f4
|
@ -10,6 +10,7 @@ from django.http import Http404
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.request import clone_request
|
from rest_framework.request import clone_request
|
||||||
|
from rest_framework import pagination
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
||||||
|
@ -187,3 +188,15 @@ class DestroyModelMixin(object):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
obj.delete()
|
obj.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
class LinkPaginationMixin(object):
|
||||||
|
pagination_serializer_class = pagination.LinkPaginationSerializer
|
||||||
|
|
||||||
|
def paginate_queryset(self, queryset, page_size=None):
|
||||||
|
page = super(LinkPaginationMixin, self).paginate_queryset(
|
||||||
|
queryset, page_size)
|
||||||
|
if page:
|
||||||
|
page_ser = self.get_pagination_serializer(page)
|
||||||
|
self.headers.update(page_ser.get_link_header())
|
||||||
|
return None # Don't use pagination serializer on response
|
||||||
|
|
|
@ -49,6 +49,35 @@ class PreviousPageField(serializers.Field):
|
||||||
return replace_query_param(url, self.page_field, page)
|
return replace_query_param(url, self.page_field, page)
|
||||||
|
|
||||||
|
|
||||||
|
class FirstPageField(serializers.Field):
|
||||||
|
"""
|
||||||
|
Field that returns a link to the first page in paginated results.
|
||||||
|
"""
|
||||||
|
page_field = 'page'
|
||||||
|
|
||||||
|
def to_native(self, value):
|
||||||
|
if not value.has_previous():
|
||||||
|
return None
|
||||||
|
request = self.context.get('request')
|
||||||
|
url = request and request.build_absolute_uri() or ''
|
||||||
|
return replace_query_param(url, self.page_field, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class LastPageField(serializers.Field):
|
||||||
|
"""
|
||||||
|
Field that returns a link to the previous page in paginated results.
|
||||||
|
"""
|
||||||
|
page_field = 'page'
|
||||||
|
|
||||||
|
def to_native(self, value):
|
||||||
|
if not value.has_next():
|
||||||
|
return None
|
||||||
|
page = value.paginator.num_pages
|
||||||
|
request = self.context.get('request')
|
||||||
|
url = request and request.build_absolute_uri() or ''
|
||||||
|
return replace_query_param(url, self.page_field, page)
|
||||||
|
|
||||||
|
|
||||||
class DefaultObjectSerializer(serializers.Field):
|
class DefaultObjectSerializer(serializers.Field):
|
||||||
"""
|
"""
|
||||||
If no object serializer is specified, then this serializer will be applied
|
If no object serializer is specified, then this serializer will be applied
|
||||||
|
@ -94,7 +123,8 @@ class BasePaginationSerializer(serializers.Serializer):
|
||||||
else:
|
else:
|
||||||
context_kwarg = {}
|
context_kwarg = {}
|
||||||
|
|
||||||
self.fields[results_field] = object_serializer(source='object_list', **context_kwarg)
|
self.fields[results_field] = object_serializer(source='object_list',
|
||||||
|
**context_kwarg)
|
||||||
|
|
||||||
|
|
||||||
class PaginationSerializer(BasePaginationSerializer):
|
class PaginationSerializer(BasePaginationSerializer):
|
||||||
|
@ -104,3 +134,19 @@ class PaginationSerializer(BasePaginationSerializer):
|
||||||
count = serializers.Field(source='paginator.count')
|
count = serializers.Field(source='paginator.count')
|
||||||
next = NextPageField(source='*')
|
next = NextPageField(source='*')
|
||||||
previous = PreviousPageField(source='*')
|
previous = PreviousPageField(source='*')
|
||||||
|
|
||||||
|
|
||||||
|
class LinkPaginationSerializer(PaginationSerializer):
|
||||||
|
""" Pagination serializer in order to build Link header """
|
||||||
|
first = FirstPageField(source='*')
|
||||||
|
last = LastPageField(source='*')
|
||||||
|
|
||||||
|
relations = ('next', 'previous', 'first', 'last')
|
||||||
|
|
||||||
|
def get_link_header(self):
|
||||||
|
link_keader_items = [
|
||||||
|
'<%s>; rel="%s"' % (link, rel)
|
||||||
|
for rel, link in self.data.items()
|
||||||
|
if (rel in self.relations and link is not None)
|
||||||
|
]
|
||||||
|
return {'Link': ', '.join(link_keader_items)}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user