Reputation: 2496
I have a very simple ListAPIView
:
class MyListView(ListAPIView):
pagination_class = QueryParamPagination
serializer_class = MyListSerializer
queryset = MyObject.objects.all()
with a simple class to define the pagination:
class QueryParamPagination(PageNumberPagination):
page_size = 2
page_size_query_param = "page_size"
max_page_size = 27
However in this scenario I will get a warning, because the result is not ordered: inconsistent results with an unordered object_list: <class 'models.MyObject'> MultilingualSoftDeleteQuerySet.
Which is fine ...
Now changing the last line to
queryset = MyObject.objects.order_by('category', 'name').all()
gets rid of the warning, however now my pagination is not working anymore. Django now uses some super defaults, all values in QueryParamPagination
are ignored, but also my global settings
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2,
}
Changing it again to
queryset = MyObject.objects.order_by('name').all()
works fine again. Is it not possible to use "double sorting" together with pagination?
Upvotes: 0
Views: 67
Reputation: 740
I'm not totally sure why that is happening, but when DRF has given me issues with querysets in the past I've often found overriding the built-in get_queryset
method can help, so you may wish to try this:
class MyListView(ListAPIView):
pagination_class = QueryParamPagination
serializer_class = MyListSerializer
def get_queryset(self):
qset = MyObject.objects.all().order_by('name')
print(f"Qset: {qset}")
return qset
Hopefully that works; if it doesn't, you may wish to try the below:
class MyListView(ListAPIView):
pagination_class = QueryParamPagination
serializer_class = MyListSerializer
def get_queryset(self):
orig_qset = MyObject.objects.all()
qset = sorted(orig_qset, key=lambda item: item.name)
print(f"Qset: {qset}")
return qset
I've left the print statements in there so you can see whether there's anything in the ordering/sorting process that is causing the bug.
If this still doesn't work, my next thoughts would be (1) try over-riding the get_paginated_response
method in a similar fashion, printing out the contents as you go, or (2) implementing your name-based ordering at the model level (inside the meta
class of your MyObject
model).
FWIW, when trying to debug any of the class-based objects in Django (Class-Based Views, Class-Based Forms, or Class-Based Django Rest Framework), I really recommend the 'Classy' pages. They are a phenomenally good tool for introspection. Links below:
Upvotes: 0