我有一个像这样的ViewSet来列出用户'数据:
class Foo(viewsets.ViewSet):
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
我想打开分页,就像ModelViewSet的默认分页一样:
{
"count": 55,
"next": "http://myUrl/?page=2",
"previous": null,
"results": [{...},{...},...,{...}]
}
只有在您使用通用视图或视图集
时才会自动执行分页
...但我的结果集根本没有分页。我该如何分页呢?
答案 0 :(得分:31)
只有在您使用通用符号时才会自动执行分页 观点或视图集
第一个障碍是将文档翻译成英文。他们打算传达的是你想要一个通用的视图集。通用视图集从generic ApiViews扩展而来,它具有用于对查询集和响应进行分页的额外类方法。
此外,您提供了自己的add(rNum, ptr);
方法,但默认的分页过程实际上由mixin处理:
fn(rNum, ptr);
简单的解决方案,使用框架代码:
list
如果您需要自定义class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
方法,那么更复杂的解决方案是,您应该按照您认为合适的方式编写它,但是采用上述mixin代码段的样式。
答案 1 :(得分:27)
对于使用DRF 3.1或更高版本的用户,他们正在更改处理分页的默认方式。有关详细信息,请参阅http://www.django-rest-framework.org/topics/3.1-announcement/。
现在,如果要为ModelViewSet启用分页,可以通过设置settings.py文件来全局执行:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
或者,如果您只想将它用于一个ModelViewSet,则可以手动为该视图集设置pagination_class。
from rest_framework.pagination import PageNumberPagination
class StandardResultsSetPagination(PageNumberPagination):
page_size = 100
page_size_query_param = 'page_size'
max_page_size = 1000
class FooViewSet(viewsets.ModelViewSet):
pagination_class = StandardResultsSetPagination
这也允许您调整仅为该视图集处理分页的方式。
DRF 3.1还引入了可以使用的新类型的默认分页方案,例如LimitOffset和Cursor。
答案 2 :(得分:3)
尝试提供类变量
paginate_by = 10 #This will paginate by 10 results per page.
创建一个自定义ViewSet
,目前只执行list
操作。
class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
pass
现在使用此自定义视图集继承您的类Foo
class Foo(ListModelViewSet):
paginate_by = 10
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
这可以帮助您实现分页。
答案 3 :(得分:2)
使用视图集和列表
在DRF中进行分页这里我处理了一个异常如果页面为空,它将显示空记录
在设置定义页面大小时,此页面大小是全局的,并且在视图中由paginator_queryset使用
REST_FRAMEWORK = {' PAGE_SIZE':10,}
在视野中 来自rest_framework import mixins,viewsets
class SittingViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin):
serializer_class = SittingSerializer
queryset = Sitting.objects.all()
serializer = serializer_class(queryset, many=True)
def list(self, request, *args, **kwargs):
queryset =self.filter_queryset(Sitting.objects.all().order_by('id'))
page = request.GET.get('page')
try:
page = self.paginate_queryset(queryset)
except Exception as e:
page = []
data = page
return Response({
"status": status.HTTP_404_NOT_FOUND,
"message": 'No more record.',
"data" : data
})
if page is not None:
serializer = self.get_serializer(page, many=True)
data = serializer.data
return self.get_paginated_response(data)
# serializer = self.get_serializer(queryset, many=True)
return Response({
"status": status.HTTP_200_OK,
"message": 'Sitting records.',
"data" : data
})
**指注意:如果您不使用Order_by,它将显示异常,因为此列表
给出无序列表。**
答案 4 :(得分:1)
如果您想对特定的ViewSet
进行分页,可以使用this answer上的一个稍微简单的变体,但无需自定义页面大小:
REST_FRAMEWORK = {
'PAGE_SIZE': 100
}
class FooViewSet(viewsets.ModelViewSet):
pagination_class = PageNumberPagination