Preemptively reduce the precision of floating point positions so that it does not change in a round-trip through the database backend.

#5160
This commit is contained in:
Kevin Turner 2017-05-22 17:33:44 -07:00
parent afc0367402
commit e9df63a467

View File

@ -7,6 +7,7 @@ from __future__ import unicode_literals
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from collections import OrderedDict, namedtuple from collections import OrderedDict, namedtuple
import decimal
from django.core.paginator import Paginator as DjangoPaginator from django.core.paginator import Paginator as DjangoPaginator
from django.core.paginator import InvalidPage from django.core.paginator import InvalidPage
@ -488,6 +489,9 @@ class CursorPagination(BasePagination):
# queries, by having a hard cap on the maximum possible size of the offset. # queries, by having a hard cap on the maximum possible size of the offset.
offset_cutoff = 1000 offset_cutoff = 1000
__rounding_down = decimal.Context(prec=14, rounding=decimal.ROUND_FLOOR)
__rounding_up = decimal.Context(prec=14, rounding=decimal.ROUND_CEILING)
def paginate_queryset(self, queryset, request, view=None): def paginate_queryset(self, queryset, request, view=None):
self.page_size = self.get_page_size(request) self.page_size = self.get_page_size(request)
if not self.page_size: if not self.page_size:
@ -756,6 +760,13 @@ class CursorPagination(BasePagination):
attr = instance[field_name] attr = instance[field_name]
else: else:
attr = getattr(instance, field_name) attr = getattr(instance, field_name)
if isinstance(attr, float):
if ordering[0][0] == '-':
attr = self.__rounding_down.create_decimal_from_float(attr)
else:
attr = self.__rounding_up.create_decimal_from_float(attr)
return six.text_type(attr) return six.text_type(attr)
def get_paginated_response(self, data): def get_paginated_response(self, data):