问题描述
DRF文档指出:
但是我使用的是 ModelViewSet
,该继承自 ViewSet
,所以我告诉自己很酷,我要做的就是将其添加到我的 settings.py
中:
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE':12,#适用于12列网格CSS框架
但是,这没用。
如果我发送GET请求获取27个项目它返回所有它们(在可浏览的API和json中)。
- 我是否认为我应该只返回12?
- Sub-问题: PAGE_SIZE是每页返回的顶级对象的数量,对吗?我看到了一些
PAGINATE_BY
的示例,但它的
在,所以我认为它已被弃用?
我正在使用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,
}
我还向中添加了
pagination_class = PageNumberPagination
这是外壳程序的验证,即Pagination类确实知道应该提供的页面大小:
>>从rest_framework.pagination导入PageNumberPagination
>> p = PageNumberPagination()
>> p.max_page_size
>> print(p.page_size)
12
的确,尽管从 GenericViewSet
和<$ c $继承,但默认情况下分页在 ModelViewSet
上不起作用c> ListMixin 。您需要手动添加它:
我组成了,它解决了该问题,并在 ModelViewSet
我会总结一下:
-
创建一个自定义mixin以使用
pagination_class
:class MyPaginationMixin(object ):
@property
def paginator(self):
与视图关联的分页器实例,或`None`。
如果没有hasattr(self,'_paginator'):
如果self.pagination_class为None:
self._paginator = None
else:
self._paginator = self。 pagination_class()
返回self._paginator
def paginate_queryset(self,queryset):
返回单页结果,如果分页
被禁用,则返回无。
如果self.paginator为None:
返回None
返回self.paginator.paginate_queryset(
queryset,self.request,view = self)
def get_paginated_response(自身,数据):
返回给定
输出数据的分页样式`Response`对象。
断言self.paginator不是None
返回self.paginator.get_paginated_response(data)
-
使您的视图集扩展到混合区域,并覆盖
ModelViewSet 的
:list()
方法class MyViewset(MyPaginationMixin,viewsets.ModelViewSet):
#因为您正在设置分页在设置上,使用以下命令:
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]]
如果页面是不是没有:
serializer = self.serializer_class(page,many = True)
return self.get_paginated_response(serializer.data)
else:
#这里出问题了...
您当然需要根据自己的需要校准此解决方案,但这会为 ModelViewSet
添加分页。 / p>
对于子问题,@Linovia的评论正确, PAGINATE_BY
已弃用, PAGE_SIZE
是响应页面大小的当前设置。
The DRF docs state that:
But I'm using a ModelViewSet
which inherits from ViewSet
, so I tell myself "Cool, all I have to do is add this to my settings.py
":
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 12, # for 12-col grid css frameworks
However, this didn't work.
If I send a GET request for 27 items it returns all of them (in both the browsable API and json).
- Am I right in thinking I should only be returned 12?
- Sub-question: PAGE_SIZE is the number of top-level objects returned per page, right? I saw a few examples with
PAGINATE_BY
but itdoesn't feature in the source so I presume it's deprecated?
I'm using DRF 3.6.3, django 1.11.2.
Edit: my settings:
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,
}
I've also added pagination_class = PageNumberPagination
to the ModelViewSet
class, without effect.
Here's the verification from the shell that the Pagination class does know the page size it's supposed to provide:
>>> from rest_framework.pagination import PageNumberPagination
>>> p = PageNumberPagination()
>>> p.max_page_size
>>> print(p.page_size)
12
It is true that pagination doesn't work by default on a ModelViewSet
despite inheriting from GenericViewSet
and the ListMixin
. You need to add it manually:
I have composed a Q&A style example which attends that problem and have tested it on a ModelViewSet
class.
I will summarize it a bit:
Create a custom mixin to utilize the
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)
Make your viewset extend that mixin and override the
list()
method of theModelViewSet
: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...
You need to calibrate this solution to your needs of course, but this will add pagination to a ModelViewSet
.
For the subquestion, @Linovia 's comment is correct, PAGINATE_BY
is deprecated and PAGE_SIZE
is the current setting for the response page size.
这篇关于Django Rest Framework全局分页参数不适用于ModelViewSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!