DRF 文档指出:
Pagination is only performed automatically if you're using the generic views or viewsets.
但是我使用的是继承自 ViewSet
的 ModelViewSet
,所以我告诉自己“酷,我所要做的就是将其添加到我的 设置中.py
":
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 12, # for 12-col grid css frameworks
但是,这不起作用。
如果我发送 27 个项目的 GET 请求,它会返回所有项目(在可浏览的 API 和 json 中)。
- 我认为我应该只返回 12 个,对吗?
- 子问题:PAGE_SIZE 是每页返回的顶级对象的数量,对吗?我看到了一些带有
PAGINATE_BY
的示例,但它 the source 中不包含此内容所以我认为它已被弃用?
我使用的是 DRF 3.6.3、django 1.11.2。
编辑:我的设置:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 12,
}
我还在 ModelViewSet
类中添加了 pagination_class = PageNumberPagination
,但没有效果。
以下是来自 shell 的验证,表明 Pagination 类确实知道它应该提供的页面大小:
>>> from rest_framework.pagination import PageNumberPagination
>>> p = PageNumberPagination()
>>> p.max_page_size
>>> print(p.page_size)
12
最佳答案
确实,尽管继承自 GenericViewSet
和 ListMixin
,但默认情况下,分页在 ModelViewSet
上不起作用。您需要手动添加:
我编写了一个 Q&A style example 来解决该问题,并在 ModelViewSet
类上对其进行了测试。
我总结一下:
创建自定义 mixin 以利用
pagination_class
:class MyPaginationMixin(object): @property def paginator(self): """ The paginator instance associated with the view, or `None`. """ if not hasattr(self, '_paginator'): if self.pagination_class is None: self._paginator = None else: self._paginator = self.pagination_class() return self._paginator def paginate_queryset(self, queryset): """ Return a single page of results, or `None` if pagination is disabled. """ if self.paginator is None: return None return self.paginator.paginate_queryset( queryset, self.request, view=self) def get_paginated_response(self, data): """ Return a paginated style `Response` object for the given output data. """ assert self.paginator is not None return self.paginator.get_paginated_response(data)
让您的 View 集扩展该 mixin 并覆盖
ModelViewSet
的list()
方法:class MyViewset(MyPaginationMixin, viewsets.ModelViewSet): # since you are setting pagination on the settings, use this: pagination_class = settings.DEFAULT_PAGINATION_CLASS def list(self, request, *args, **kwargs): response = dict( super(MyViewSet, self).list(self, *args, **kwargs).data) page = self.paginate_queryset(response['results']) if page is not None: serializer = self.serializer_class(page, many=True) return self.get_paginated_response(serializer.data) else: # Something went wrong here...
当然,您需要根据您的需求校准此解决方案,但这将为 ModelViewSet
添加分页。
对于子问题,@Linovia 的评论是正确的,PAGINATE_BY
已弃用,PAGE_SIZE
是响应页面大小的当前设置。
关于python - Django Rest框架全局分页参数不适用于ModelViewSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44722221/