我有一个viewsets.ViewSet
的简单子类,如下所示:
from rest_framework import viewsets
from rest_framework.response import Response
from ..models import Entry, Sitting, Source, Venue
from .serializers import (
SittingSerializer, SittingWithEntriesSerializer,
)
class SittingViewSet(viewsets.ViewSet):
def list(self, request, version=None):
queryset = Sitting.objects.order_by('id')
serializer = SittingSerializer(
queryset, many=True, context={'request': request}
)
return Response(serializer.data)
def retrieve(self, request, pk=None, version=None):
prefetch_qs = Entry.objects.select_related('speaker')
queryset = Sitting.objects.order_by('id') \
.prefetch_related(Prefetch('entry_set', queryset=prefetch_qs))
sitting = get_object_or_404(queryset, pk=pk)
serializer = SittingWithEntriesSerializer(
sitting, context={'request': request}
)
return Response(serializer.data)
但是,列表视图不是分页的,因为它是使用ModelViewSet
的子类。我正在使用的设置是:
# Django Rest Framework settings:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('pombola.api.permissions.ReadOnly',),
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'PAGE_SIZE': 10,
}
documentation建议查看mixins.ListModelMixin和generics.GenericAPIView类的源代码,但我不能轻易看到如何重新应用他们的工作来将结果分页到这些ViewSet方法
有人可以建议最简单的方法是更改此示例以获取list
视图的分页吗?
答案 0 :(得分:1)
您覆盖了list方法,因此它不会对您的数据进行分页。
如果你检查ListModelMixins
我认为这可能是你的答案:
class SittingViewSet(
viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.RetrieveModelMixin):
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(
Sitting.objects.order_by('id')
)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = SittingSerializer(
page,
many=True,
context={'request': request}
)
return self.get_paginated_response(serializer.data)
serializer = SittingSerializer(
queryset,
many=True,
context={'request': request}
)
return Response(serializer.data)
答案 1 :(得分:1)
尽管这是一个很晚的答案,但我为Django Rest Framework写了一个Q&A style example,它使非通用视图集具有分页功能。
默认情况下,只有viewsets.GenericViewSet
具有自动分页(如果您在当然的设置中启用分页),因为它继承自generics.GenericAPIView
。
这给你留下了两个选择:
简单方法:
mixins.ListModelMixin
提供分页,因此您只需按如下方式声明您的视图集:
class SittingViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
现在你有一个list()
分页方法。
更难的方式: *
您可以按照above给出的示例,在视图集中创建分页方法。
list()
代码必须源自上面提供的mixins.ListModelMixin
的源代码
可以从文档或[paginator()
] [4]
paginate_queryset()
,get_paginated_response()
和generics.GenericApiView
方法
醇>
答案 2 :(得分:0)
使用视图集和列表
在DRF中进行分页这里我处理了一个异常如果页面为空,它将显示空记录
在设置中定义页面大小,此页面大小是全局的,并且在视图中由paginator_queryset使用
REST_FRAMEWORK = { 'PAGE_SIZE':10, }
在视图中
from 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,它将显示异常,因为此列表
给出无序列表。**
答案 3 :(得分:0)
**使用APIView在DRF中进行分页,如果没有序列化程序类**
这里我使用了django paginator,非常简单
在视图中
from rest_framework.views import APIView
class SittingView(APIView):
"""This is a API code so when at e.g. (url /sitting-record/?page=2) is entered it will show 10 records for page 2 and if page is empty it will show empty"""
def get(self, request, format=None):
"""Here 10 is the page size, that means 10 record per page"""
sitting = Sitting.objects.all().order_by('id')
sitting_paginator = Paginator(sitting, 10)
"""this gets the page page from url and if not given it set default page is 1"""
page = request.GET.get('page')
page = 1 if not page else page
try:
paginated_setting = sitting_paginator.page(page)
except Exception as e:
paginated_setting = []
"""you can retrieve or iterate the records fields from paginator_setting and then send the data in response"""
data = {
"setting records" : paginated_setting,
}
return Response({
"status" : status.HTTP_200_OK,
"messgae" : "Sitting content",
"data" : data
})
答案 4 :(得分:0)
简单的解决方案。让我们以auth模型为例。
from django.contrib.auth.models import User
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets
from .serializer import UserSerializer
class UserViewSet(viewsets.ViewSet):
def list(self, request):
queryset = User.objects.all()
pagination = PageNumberPagination()
qs = pagination.paginate_queryset(queryset, request)
serializer = UserSerializer(qs, many=True)
return pagination.get_paginated_response(serializer.data)