2013-04-25 15:47:34 +04:00
|
|
|
"""
|
|
|
|
Pagination serializers determine the structure of the output that should
|
|
|
|
be used for paginated responses.
|
|
|
|
"""
|
2013-02-05 00:55:35 +04:00
|
|
|
from __future__ import unicode_literals
|
2012-09-30 20:31:28 +04:00
|
|
|
from rest_framework import serializers
|
2012-11-08 01:07:24 +04:00
|
|
|
from rest_framework.templatetags.rest_framework import replace_query_param
|
2012-09-30 20:31:28 +04:00
|
|
|
|
|
|
|
|
2012-11-08 01:09:26 +04:00
|
|
|
class NextPageField(serializers.Field):
|
2012-10-01 18:49:19 +04:00
|
|
|
"""
|
|
|
|
Field that returns a link to the next page in paginated results.
|
|
|
|
"""
|
2012-11-08 01:09:26 +04:00
|
|
|
page_field = 'page'
|
|
|
|
|
2014-09-12 12:49:35 +04:00
|
|
|
def to_representation(self, value):
|
2012-09-30 20:31:28 +04:00
|
|
|
if not value.has_next():
|
|
|
|
return None
|
|
|
|
page = value.next_page_number()
|
2012-10-01 18:49:19 +04:00
|
|
|
request = self.context.get('request')
|
2012-11-09 01:47:54 +04:00
|
|
|
url = request and request.build_absolute_uri() or ''
|
2012-11-08 01:07:24 +04:00
|
|
|
return replace_query_param(url, self.page_field, page)
|
2012-09-30 20:31:28 +04:00
|
|
|
|
|
|
|
|
2012-11-08 01:09:26 +04:00
|
|
|
class PreviousPageField(serializers.Field):
|
2012-10-01 18:49:19 +04:00
|
|
|
"""
|
|
|
|
Field that returns a link to the previous page in paginated results.
|
|
|
|
"""
|
2012-11-08 01:09:26 +04:00
|
|
|
page_field = 'page'
|
|
|
|
|
2014-09-12 12:49:35 +04:00
|
|
|
def to_representation(self, value):
|
2012-09-30 20:31:28 +04:00
|
|
|
if not value.has_previous():
|
|
|
|
return None
|
|
|
|
page = value.previous_page_number()
|
2012-10-01 18:49:19 +04:00
|
|
|
request = self.context.get('request')
|
2012-11-09 01:47:54 +04:00
|
|
|
url = request and request.build_absolute_uri() or ''
|
2012-11-08 01:07:24 +04:00
|
|
|
return replace_query_param(url, self.page_field, page)
|
2012-09-30 20:31:28 +04:00
|
|
|
|
|
|
|
|
2014-09-12 00:48:54 +04:00
|
|
|
class DefaultObjectSerializer(serializers.ReadOnlyField):
|
2013-01-27 00:54:41 +04:00
|
|
|
"""
|
|
|
|
If no object serializer is specified, then this serializer will be applied
|
|
|
|
as the default.
|
|
|
|
"""
|
|
|
|
|
2014-09-03 18:52:41 +04:00
|
|
|
def __init__(self, source=None, many=None, context=None):
|
|
|
|
# Note: Swallow context and many kwargs - only required for
|
|
|
|
# eg. ModelSerializer.
|
2013-01-27 00:54:41 +04:00
|
|
|
super(DefaultObjectSerializer, self).__init__(source=source)
|
|
|
|
|
|
|
|
|
2012-10-01 18:49:19 +04:00
|
|
|
class BasePaginationSerializer(serializers.Serializer):
|
|
|
|
"""
|
|
|
|
A base class for pagination serializers to inherit from,
|
|
|
|
to make implementing custom serializers more easy.
|
|
|
|
"""
|
2012-10-02 13:40:43 +04:00
|
|
|
results_field = 'results'
|
2012-10-01 18:49:19 +04:00
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
"""
|
|
|
|
Override init to add in the object serializer field on-the-fly.
|
|
|
|
"""
|
|
|
|
super(BasePaginationSerializer, self).__init__(*args, **kwargs)
|
2012-10-02 13:40:43 +04:00
|
|
|
results_field = self.results_field
|
2013-01-23 11:38:13 +04:00
|
|
|
|
2014-09-02 20:41:23 +04:00
|
|
|
try:
|
|
|
|
object_serializer = self.Meta.object_serializer_class
|
|
|
|
except AttributeError:
|
|
|
|
object_serializer = DefaultObjectSerializer
|
|
|
|
|
|
|
|
self.fields[results_field] = serializers.ListSerializer(
|
|
|
|
child=object_serializer(),
|
|
|
|
source='object_list'
|
|
|
|
)
|
2014-09-11 16:20:44 +04:00
|
|
|
self.fields[results_field].bind(results_field, self, self)
|
2012-09-30 20:31:28 +04:00
|
|
|
|
2012-10-01 18:49:19 +04:00
|
|
|
|
|
|
|
class PaginationSerializer(BasePaginationSerializer):
|
|
|
|
"""
|
|
|
|
A default implementation of a pagination serializer.
|
|
|
|
"""
|
2014-09-12 00:48:54 +04:00
|
|
|
count = serializers.ReadOnlyField(source='paginator.count')
|
2012-10-01 18:49:19 +04:00
|
|
|
next = NextPageField(source='*')
|
|
|
|
previous = PreviousPageField(source='*')
|