J'ai un ViewSet comme celui-ci pour répertorier les données des utilisateurs:
class Foo(viewsets.ViewSet):
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
Je veux activer la pagination comme la pagination par défaut pour ModelViewSet:
{
"count": 55,
"next": "http://myUrl/?page=2",
"previous": null,
"results": [{...},{...},...,{...}]
}
Le document officiel dit:
La pagination n'est effectuée automatiquement que si vous utilisez les vues ou les ensembles de vues génériques
... mais mon jeu de résultats n'est pas du tout paginé. Comment puis-je le paginer?
La pagination n'est effectuée automatiquement que si vous utilisez les vues ou les ensembles de vues génériques
Le premier barrage routier traduit les documents en anglais. Ce qu'ils avaient l'intention de transmettre, c'est que vous souhaitiez un ensemble de vues générique. Les ensembles de vues génériques s'étendent de ApiViews génériques qui ont des méthodes de classe supplémentaires pour paginer les ensembles de requêtes et les réponses.
De plus, vous fournissez votre propre méthode list
, mais le processus de pagination par défaut est en fait géré par le 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)
La solution simple, utilisez le code framework:
class Foo(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer = UserSerializer
La solution la plus complexe serait si vous avez besoin d'une méthode list
personnalisée, alors vous devriez l'écrire comme bon vous semble mais dans le style de l'extrait de code mixin ci-dessus.
Pour ceux qui utilisent DRF 3.1 ou supérieur, ils changent la façon dont la pagination est gérée par défaut. Voir http://www.Django-rest-framework.org/topics/3.1-announcement/ pour plus de détails.
Maintenant, si vous souhaitez activer la pagination pour un ModelViewSet, vous pouvez le faire globalement en définissant dans votre fichier settings.py:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
Ou si vous le souhaitez uniquement pour un ModelViewSet, vous pouvez définir manuellement la pagination_class pour cet ensemble de vues uniquement.
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
Cela vous permet également de modifier la façon dont la pagination est gérée pour cet ensemble de vues uniquement.
DRF 3.1 a également introduit de nouveaux types de schémas de pagination par défaut que vous pouvez utiliser tels que LimitOffset et Cursor.
Essayez de fournir une variable de classe
paginate_by = 10 #This will paginate by 10 results per page.
Créez un ViewSet
personnalisé qui n'effectue que list
comme votre cas ici.
class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
pass
Héritez maintenant de votre classe Foo
avec cet ensemble de vues personnalisé
class Foo(ListModelViewSet):
paginate_by = 10
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
Cela devrait vous aider à faire fonctionner la pagination.
Pagination dans DRF à l'aide des ensembles de vues et de la liste
Ici, j'ai géré une exception Si la page est vide, elle affichera des enregistrements vides
En définissant définir la taille de la page, cette taille de page est globale et elle est utilisée par paginator_queryset en vue
REST_FRAMEWORK = {'PAGE_SIZE': 10,}
Au vu de rest_framework, importez les mixins, les ensembles de vues
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
})
**> Remarque: Si vous n'utilisez pas Order_by, il affichera une exception car cette liste
donne une liste non ordonnée. **
Une variation légèrement plus simple sur cette réponse si vous voulez une pagination pour un ViewSet
particulier, mais n'avez pas besoin de personnaliser la taille de la page:
REST_FRAMEWORK = {
'PAGE_SIZE': 100
}
class FooViewSet(viewsets.ModelViewSet):
pagination_class = PageNumberPagination