django-rest-framework/rest_framework/pagination.py

91 lines
3.0 KiB
Python
Raw Normal View History

2012-09-30 20:31:28 +04:00
from rest_framework import serializers
# TODO: Support URLconf kwarg-style paging
class PageField(serializers.Field):
page_field = 'page'
class NextPageField(PageField):
2012-10-01 18:49:19 +04:00
"""
Field that returns a link to the next page in paginated results.
"""
2012-09-30 20:31:28 +04:00
def to_native(self, value):
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')
relative_url = '?%s=%d' % (self.page_field, page)
2012-10-01 18:49:19 +04:00
if request:
for field, value in request.QUERY_PARAMS.iteritems():
if field != self.page_field:
relative_url += '&%s=%s' % (field, value)
2012-10-01 18:49:19 +04:00
return request.build_absolute_uri(relative_url)
return relative_url
2012-09-30 20:31:28 +04:00
class PreviousPageField(PageField):
2012-10-01 18:49:19 +04:00
"""
Field that returns a link to the previous page in paginated results.
"""
2012-09-30 20:31:28 +04:00
def to_native(self, value):
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')
relative_url = '?%s=%d' % (self.page_field, page)
2012-10-01 18:49:19 +04:00
if request:
for field, value in request.QUERY_PARAMS.iteritems():
if field != self.page_field:
relative_url += '&%s=%s' % (field, value)
return request.build_absolute_uri(relative_url)
2012-10-01 18:49:19 +04:00
return relative_url
2012-09-30 20:31:28 +04:00
2012-10-01 18:49:19 +04:00
class PaginationSerializerOptions(serializers.SerializerOptions):
"""
An object that stores the options that may be provided to a
pagination serializer by using the inner `Meta` class.
Accessible on the instance as `serializer.opts`.
"""
def __init__(self, meta):
super(PaginationSerializerOptions, self).__init__(meta)
self.object_serializer_class = getattr(meta, 'object_serializer_class',
serializers.Field)
class BasePaginationSerializer(serializers.Serializer):
"""
A base class for pagination serializers to inherit from,
to make implementing custom serializers more easy.
"""
_options_class = PaginationSerializerOptions
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)
results_field = self.results_field
2012-10-01 18:49:19 +04:00
object_serializer = self.opts.object_serializer_class
self.fields[results_field] = object_serializer(source='object_list')
2012-09-30 20:31:28 +04:00
def to_native(self, obj):
"""
Prevent default behaviour of iterating over elements, and serializing
each in turn.
"""
return self.convert_object(obj)
2012-10-01 18:49:19 +04:00
class PaginationSerializer(BasePaginationSerializer):
"""
A default implementation of a pagination serializer.
"""
count = serializers.Field(source='paginator.count')
next = NextPageField(source='*')
previous = PreviousPageField(source='*')