在Django Rest Framework中使用两个字段的order时,分页没有使用正确的值

czfnxgou  于 2023-05-19  发布在  Go
关注(0)|答案(1)|浏览(156)

我有一个非常简单的ListAPIView

class MyListView(ListAPIView):
    pagination_class = QueryParamPagination
    serializer_class = MyListSerializer
    queryset = MyObject.objects.all()

用一个简单的类来定义分页:

class QueryParamPagination(PageNumberPagination):
    page_size = 2
    page_size_query_param = "page_size"
    max_page_size = 27

然而,在这种情况下,我会得到一个警告,因为结果是无序的:inconsistent results with an unordered object_list: <class 'models.MyObject'> MultilingualSoftDeleteQuerySet.哪个好...
现在将最后一行改为

queryset = MyObject.objects.order_by('category', 'name').all()

摆脱了警告,但是现在我的分页不再工作了。Django现在使用了一些超级默认值,QueryParamPagination中的所有值都被忽略了,但我的全局设置也被忽略了。

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 2,
}

再次更改为

queryset = MyObject.objects.order_by('name').all()

又能正常工作了是否可以将“双重排序”与分页一起使用?

1cklez4t

1cklez4t1#

我不完全确定为什么会发生这种情况,但是当DRF在过去给我的查询集问题时,我经常发现覆盖内置的get_queryset方法可以帮助,所以你可能希望尝试一下:

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

希望这行得通;如果没有,您可能希望尝试以下操作:

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

我把print语句留在那里,这样你就可以看到在排序/排序过程中是否有什么东西导致了这个bug。
如果这仍然不起作用,我的下一个想法是(1)尝试以类似的方式覆盖get_paginated_response方法,打印出内容,或者(2)在模型级别(在MyObject模型的meta类中)实现基于名称的排序。
FWIW,当尝试调试Django中任何基于类的对象(基于类的视图,基于类的表单或基于类的Django Rest框架)时,我真的推荐'Classy'页面。它们是一个非常好的内省工具。以下链接:
Classy DRF
Classy Class-Based Views
Classy Forms

相关问题