1

I have the following class based view that works as expected and paginates the results as required with parameters http://127.0.0.1:8000/api/collection/fromdetroit?page=1 >> ?page=2 etc

class ListReleasesCollectionView(APIView):

    def get(self, request, format=None, *args, **kwargs):
        try:
            releases = ReleasesAll.objects.raw('SELECT releases.*, \'\' as num FROM releases_all releases INNER JOIN release_artists ra ON ra.release_id=releases.id LEFT JOIN genre_artists ON genre_artists.artist=ra.artists LEFT JOIN genre_labels ON genre_labels.label=releases.label_no_country WHERE genre_artists.genre=%s OR genre_labels.genre=%s GROUP by releases.id ORDER BY releases.date DESC',(kwargs['collection'],kwargs['collection']))
            paginator = PageNumberPagination()
            result_page = paginator.paginate_queryset(releases, request)
            serializer = ReleasesSerializer(result_page, many=True, context={'request': request})
            response = Response({'results':{'image_url':'', 'page_header':'','releases': serializer.data}}, status=status.HTTP_200_OK)
            return response

        except ReleasesAll.DoesNotExist:
            return Response(
                data = {
                    "message": "{} does not exist".format(kwargs["collection"])
                },
                status=status.HTTP_404_NOT_FOUND
            )

However, it runs incredibly slowly because it has to download ALL results first and then paginate after. Here are the results from Django Toolbar.

enter image description here

I would like to only download 60 results at a time as there are thousands of results returned above.

Pagination settings in settings.py

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 10
}
Franco
  • 2,846
  • 7
  • 35
  • 54
  • Why aren't you using a normal orm query? That's a fairly complex query but certainly possible to express without using raw. – Daniel Roseman Sep 17 '18 at 16:45
  • I wasn't sure how to do this using ORM so wanted to focus on completing the endpoint before refactoring to ORM. But I'd be happy to see an example of how its done :) – Franco Sep 17 '18 at 16:47
  • Can you explain in plain English what your query is supposed to do? It would probably be a lot cleaner if it was ORM. Also, add a LIMIT? – Athena Sep 17 '18 at 17:04
  • My advice would be that you write your own pagination. – Linovia Sep 18 '18 at 08:20

1 Answers1

0

Add your pagination class. create pagination_class.py.

from rest_framework.pagination import PageNumberPagination


class StandardResultsSetPagination(PageNumberPagination):
    page_size_query_param = 'limit'

Add this into settings.py.

REST_FRAMEWORK = {
    ...
    'DEFAULT_PAGINATION_CLASS': 'app_name.pagination_class.StandardResultsSetPagination',
 ...
}
a_k_v
  • 1,558
  • 7
  • 18