0
After browsing through django-rest-framework code I came up with this idea:
-
Override default
Paginator
class for a given view:class RestaurantList(generics.ListAPIView): pagination_class = custom.LimitOffsetPagination
-
Create custom pagination class:
class LimitOffsetPagination(pagination.LimitOffsetPagination): def __init__(self): self._countable_queryset = None self._was_counted = False def was_initialized(self): return self._countable_queryset is not None def set_raw_queryset_for_count(self, queryset: QuerySet): self._countable_queryset = queryset def paginate_queryset(self, queryset, request, view=None): self.limit = self.get_limit(request) if self.limit is None: return None self.offset = self.get_offset(request) self.count = self._countable_queryset.count() self.request = request if self.count > self.limit and self.template is not None: self.display_page_controls = True return list(queryset[self.offset:self.offset + self.limit])
-
Override views
paginator
property:@property def paginator(self): paginator = super().paginator if not paginator.was_initialized(): paginator.set_raw_queryset_for_count(Restaurant.objects.all()) return paginator
Now the count query will look a bit more friendly
SELECT COUNT(*) AS "__count" FROM "restaurants_restaurant"
Source:stackexchange.com