Python Django Rest Framework:打开 ViewSet 上的分页(如 ModelViewSet 分页)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31785966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django Rest Framework: turn on pagination on a ViewSet (like ModelViewSet pagination)
提问by floatingpurr
I have a ViewSet like this one to list users' data:
我有一个像这样的 ViewSet 来列出用户的数据:
class Foo(viewsets.ViewSet):
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
I want to turn on pagination like the default pagination for ModelViewSet:
我想像 ModelViewSet 的默认分页一样打开分页:
{
"count": 55,
"next": "http://myUrl/?page=2",
"previous": null,
"results": [{...},{...},...,{...}]
}
The official docsays:
官方文档说:
Pagination is only performed automatically if you're using the generic views or viewsets
只有在使用通用视图或视图集时才会自动执行分页
...but my resultset is not paginated at all. How can I paginate it?
...但我的结果集根本没有分页。我怎样才能对其进行分页?
采纳答案by Mark Galloway
Pagination is only performed automatically if you're using the generic views or viewsets
只有在使用通用视图或视图集时才会自动执行分页
The first roadblock is translating the docs to english. What they intended to convey is that you desire a generic viewset. The generic viewsets extend from generic ApiViewswhich have extra class methods for paginating querysets and responses.
第一个障碍是将文档翻译成英文。他们想要传达的是你想要一个通用的视图集。通用视图集从通用 ApiViews 扩展而来,通用 ApiViews具有用于对查询集和响应进行分页的额外类方法。
Additionally, you're providing your own list
method, but the default pagination process is actually handled by the mixin:
此外,您提供了自己的list
方法,但默认的分页过程实际上是由mixin处理的:
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)
The easy solution, use the framework code:
简单的解决方案,使用框架代码:
class Foo(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer = UserSerializer
The more complex solution would be if you need a custom list
method, then you should write it as you see fit but in the style of the above mixin code snippet.
更复杂的解决方案是,如果您需要自定义list
方法,那么您应该按照您认为合适的方式编写它,但要采用上述混合代码片段的风格。
回答by Arpit Goyal
Try providing a class variable
尝试提供一个类变量
paginate_by = 10 #This will paginate by 10 results per page.
Create a Custom ViewSet
which performs only list
operation as your case for here currently.
创建一个自定义ViewSet
,该自定义list
当前仅根据您的情况执行操作。
class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
pass
Now inherit your class Foo
with this custom made viewset
现在Foo
用这个定制的视图集继承你的类
class Foo(ListModelViewSet):
paginate_by = 10
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
This should help you get the pagination working.
这应该可以帮助您使分页正常工作。
回答by jeffjv
For those using DRF 3.1 or higher, they are changing the default way pagination is handled. See http://www.django-rest-framework.org/topics/3.1-announcement/for details.
对于使用 DRF 3.1 或更高版本的用户,他们正在更改处理分页的默认方式。有关详细信息,请参阅http://www.django-rest-framework.org/topics/3.1-announcement/。
Now if you want to enable pagination for a ModelViewSet you can either do it globally by setting in your settings.py file:
现在,如果您想为 ModelViewSet 启用分页,您可以通过在 settings.py 文件中进行设置来全局执行此操作:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
Or if you just want it for one ModelViewSet you can manually set the pagination_class for just that viewset.
或者,如果您只想要一个 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
This also allows you to tweak the way the pagination is handled for just that viewset.
这还允许您调整仅针对该视图集处理分页的方式。
DRF 3.1 also has introduced new types of default pagination schemes that you can use such as LimitOffset and Cursor.
DRF 3.1 还引入了可以使用的新型默认分页方案,例如 LimitOffset 和 Cursor。
回答by Vinay Kumar
Pagination in DRF using viewsets and list
使用视图集和列表在 DRF 中进行分页
Here I have handled a exception If page is empty it will show empty records
这里我处理了一个异常如果页面为空,它将显示空记录
In setting define the page size, this page size is global and it is used by paginator_queryset in view
在设置中定义页面大小,这个页面大小是全局的,在视图中被paginator_queryset使用
REST_FRAMEWORK = { 'PAGE_SIZE': 10, }
REST_FRAMEWORK = { 'PAGE_SIZE': 10, }
In view from rest_framework import mixins, viewsets
在从 rest_framework 导入 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
})
**> Note: If you not use Order_by it will show exception because this list
**> 注意:如果你不使用 Order_by 它会显示异常,因为这个列表
gives unordered list.**
给出无序列表。**
回答by morningstar
A slightly simpler variation on this answerif you want pagination for a particular ViewSet
, but don't need to customize the page size:
如果您想要为特定的分页,但不需要自定义页面大小,则此答案的一个稍微简单的变体ViewSet
:
REST_FRAMEWORK = {
'PAGE_SIZE': 100
}
class FooViewSet(viewsets.ModelViewSet):
pagination_class = PageNumberPagination