Ich habe ein ViewSet wie dieses, um die Benutzerdaten aufzulisten:
class Foo(viewsets.ViewSet):
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
Ich möchte die Paginierung wie die Standardpaginierung für ModelViewSet aktivieren:
{
"count": 55,
"next": "http://myUrl/?page=2",
"previous": null,
"results": [{...},{...},...,{...}]
}
Das offizielle Dokument sagt:
Die Paginierung wird nur automatisch durchgeführt, wenn Sie die allgemeinen Ansichten oder Ansichten-Sets verwenden
... aber mein Resultset ist überhaupt nicht paginiert. Wie kann ich es paginieren?
Die Paginierung wird nur automatisch durchgeführt, wenn Sie die allgemeinen Ansichten oder Ansichten-Sets verwenden
Die erste Straßensperre ist die Übersetzung der Dokumente ins Englische. Was sie vermitteln wollten, ist, dass Sie ein generisches Viewset wünschen. Die generischen Viewsets reichen von generische ApiViews , die über zusätzliche Klassenmethoden zum Paginieren von Abfragesets und Antworten verfügen.
Darüber hinaus stellen Sie Ihre eigene list
-Methode bereit, aber der Standard-Paginierungsprozess wird tatsächlich von mixin ausgeführt:
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)
Die einfache Lösung, verwenden Sie den Framework-Code:
class Foo(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer = UserSerializer
Die komplexere Lösung wäre, wenn Sie eine benutzerdefinierte list
-Methode benötigen, die Sie nach Belieben schreiben sollten, jedoch im Stil des obigen Mixin-Code-Snippets.
Für diejenigen, die DRF 3.1 oder höher verwenden, wird die Standardmethode für die Paginierung geändert. Siehe http://www.Django-rest-framework.org/topics/3.1-announcement/ für Details.
Wenn Sie nun die Paginierung für ein ModelViewSet aktivieren möchten, können Sie dies entweder global tun, indem Sie Folgendes in Ihrer settings.py-Datei festlegen:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
Oder wenn Sie es nur für ein ModelViewSet möchten, können Sie die Paginierungsklasse für nur dieses Viewset manuell festlegen.
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
Auf diese Weise können Sie auch die Art und Weise anpassen, wie die Paginierung nur für dieses Viewset behandelt wird.
DRF 3.1 hat auch neue Arten von Standard-Paginierungsschemata eingeführt, die Sie verwenden können, z. B. LimitOffset und Cursor.
Versuchen Sie, eine Klassenvariable bereitzustellen
paginate_by = 10 #This will paginate by 10 results per page.
Erstellen Sie ein benutzerdefiniertes ViewSet
, das derzeit nur die list
Operation ausführt, wie Sie es hier tun.
class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
pass
Erben Sie nun Ihre Klasse Foo
mit diesem benutzerdefinierten Ansichten-Set
class Foo(ListModelViewSet):
paginate_by = 10
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
Dies sollte Ihnen helfen, die Paginierung zum Laufen zu bringen.
Paginierung in DRF unter Verwendung von Viewsets und Listen
Hier habe ich eine Ausnahme behandelt. Wenn die Seite leer ist, werden leere Datensätze angezeigt
Bei der Festlegung der Seitengröße ist diese Seitengröße global und wird von paginator_queryset in view verwendet
REST_FRAMEWORK = {'PAGE_SIZE': 10,}
In der Ansicht von rest_framework werden Mixins und Viewsets importiert
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
})
**> Hinweis: Wenn Sie Order_by nicht verwenden, wird aufgrund dieser Liste eine Ausnahme angezeigt
gibt ungeordnete Liste. **
Eine etwas einfachere Variante von diese Antwort , wenn Sie eine Paginierung für ein bestimmtes ViewSet
wünschen, aber die Seitengröße nicht anpassen müssen:
REST_FRAMEWORK = {
'PAGE_SIZE': 100
}
class FooViewSet(viewsets.ModelViewSet):
pagination_class = PageNumberPagination