Skip to content

Instantly share code, notes, and snippets.

@martin056
Created June 7, 2019 13:47
Show Gist options
  • Save martin056/1b0cda49dccc1eacfcde6dfbd2a544cc to your computer and use it in GitHub Desktop.
Save martin056/1b0cda49dccc1eacfcde6dfbd2a544cc to your computer and use it in GitHub Desktop.
Main Idea - DECOUPLE serialization & pagination
class LimitOffsetPrepagination(LimitOffsetPagination):
def __init__(self, request):
self.request = request
def paginate_queryset(self, queryset, postpagination=None):
self.results = super().paginate_queryset(queryset=queryset, request=self.request)
if postpagination:
self.results = postpagination(self.results)
return self.results
class LimitOffsetPrepaginationSerializer:
class ItemSerializer(serializers.Serializer):
pass
def __init__(self, prepaginator, results=None):
if results is None:
results = []
self.results = results
self.prepaginator = prepaginator
@property
def data(self):
return {
'limit': self.prepaginator.limit,
'offset': self.prepaginator.offset,
'count': self.prepaginator.count,
'next': self.prepaginator.get_next_link(),
'previous': self.prepaginator.get_previous_link(),
'results': self.ItemSerializer(self.results, many=True).data
}
# ===============================================================================
class BookingListApi(APIView):
class Prepaginator(LimitOffsetPrepagination):
default_limit = 10
max_limit = 50
class OutputSerialzier(LimitOffsetPrepaginationSerializer):
class ItemSerializer(serializers.Serializer):
id = serializers.IntegerField()
def get(self, request, *args, **kwargs):
prepaginator = self.Prepaginator(request=request)
paginated_bookings = get_bookings_list(
location=self.location,
filters=request.GET,
prepaginator=prepaginator
)
serializer = self.OutputSerialzier(results=paginated_bookings, prepaginator=prepaginator)
return Response(serializer.data)
# ============================================================================
def get_bookings_list(
*,
filters: dict=None,
prepaginator: LimitOffsetPrepagination=None
) -> QuerySetType[Booking]:
bookings = Booking.objects.all()
if filters:
bookings = BookingFilterV2(params=filters, queryset=bookings).qs
def attach_precalculated_fields(results):
"""
Some expensive on-the-go property calculations for the results here...
"""
return results
if prepaginator is not None:
return prepaginator.paginate_queryset(queryset=bookings, postpagination=attach_precalculated_fields)
return attach_precalculated_fields(bookings)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment