Created
June 7, 2019 13:47
-
-
Save martin056/1b0cda49dccc1eacfcde6dfbd2a544cc to your computer and use it in GitHub Desktop.
Main Idea - DECOUPLE serialization & pagination
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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