python - modelserializer - Los parámetros de paginación global de Django rest framework no funcionan para ModelViewSet
partial update django rest framework (2)
Deberia de funcionar. Si no lo hace y no tiene errores tipográficos, mire los registros del servidor y puede encontrar algo que le diga que la paginación sin orden no funcionará:
xxxx/django/core/paginator.py:112: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: ....
Para solucionarlo, asegúrese de especificar un orden en el Meta del modelo o establecer un order_by
dentro del ModelViewSet
de queryset
.
Los documentos DRF dicen que:
La paginación solo se realiza automáticamente si está utilizando vistas genéricas o conjuntos de vistas.
Pero estoy usando un ModelViewSet
que hereda de ViewSet
, así que me digo a mí mismo "Genial, todo lo que tengo que hacer es agregar esto a mi settings.py
":
''DEFAULT_PAGINATION_CLASS'': ''rest_framework.pagination.PageNumberPagination'',
''PAGE_SIZE'': 12, # for 12-col grid css frameworks
Sin embargo, esto no funcionó.
Si envío una solicitud GET para 27 elementos, los devuelve a todos (tanto en la API navegable como en json).
- ¿Estoy en lo cierto al pensar que solo debería ser devuelto 12?
- Subpregunta : PAGE_SIZE es el número de objetos de nivel superior que se devuelve por página, ¿no? Vi algunos ejemplos con
PAGINATE_BY
pero no aparece en la fuente, entonces supongo que está obsoleto.
Estoy usando DRF 3.6.3, django 1.11.2.
Editar: mi configuración:
REST_FRAMEWORK = {
''DEFAULT_PERMISSION_CLASSES'': (
''rest_framework.permissions.IsAuthenticated'',
),
''DEFAULT_AUTHENTICATION_CLASSES'': (
''rest_framework.authentication.TokenAuthentication'',
''rest_framework.authentication.SessionAuthentication'',
),
''DEFAULT_RENDERER_CLASSES'': (
''rest_framework.renderers.JSONRenderer'',
''rest_framework.renderers.BrowsableAPIRenderer'',
),
''DEFAULT_PAGINATION_CLASS'': ''rest_framework.pagination.PageNumberPagination'',
''PAGE_SIZE'': 12,
}
También agregué pagination_class = PageNumberPagination
a la clase ModelViewSet
, sin efecto.
Aquí está la verificación del shell de que la clase Pagination sabe el tamaño de página que se supone que debe proporcionar:
>>> from rest_framework.pagination import PageNumberPagination
>>> p = PageNumberPagination()
>>> p.max_page_size
>>> print(p.page_size)
12
Es cierto que la paginación no funciona de manera predeterminada en un ModelViewSet
pesar de heredar de GenericViewSet
y ListMixin
. Necesitas agregarlo manualmente:
He compuesto un ejemplo de estilo de preguntas y respuestas que atiende ese problema y lo he probado en una clase ModelViewSet
.
Lo resumiré un poco:
Cree una mezcla personalizada para utilizar
pagination_class
:class MyPaginationMixin(object): @property def paginator(self): """ The paginator instance associated with the view, or `None`. """ if not hasattr(self, ''_paginator''): if self.pagination_class is None: self._paginator = None else: self._paginator = self.pagination_class() return self._paginator def paginate_queryset(self, queryset): """ Return a single page of results, or `None` if pagination is disabled. """ if self.paginator is None: return None return self.paginator.paginate_queryset( queryset, self.request, view=self) def get_paginated_response(self, data): """ Return a paginated style `Response` object for the given output data. """ assert self.paginator is not None return self.paginator.get_paginated_response(data)
Haga que su viewset extienda esa mezcla y anule el método
list()
deModelViewSet
:class MyViewset(MyPaginationMixin, viewsets.ModelViewSet): # since you are setting pagination on the settings, use this: pagination_class = settings.DEFAULT_PAGINATION_CLASS def list(self, request, *args, **kwargs): response = dict( super(MyViewSet, self).list(self, *args, **kwargs).data) page = self.paginate_queryset(response[''results'']) if page is not None: serializer = self.serializer_class(page, many=True) return self.get_paginated_response(serializer.data) else: # Something went wrong here...
Necesita calibrar esta solución para sus necesidades, por supuesto, pero esto agregará paginación a un ModelViewSet
.
Para la pregunta, el comentario de @Linovia es correcto, PAGINATE_BY
está en desuso y PAGE_SIZE
es la configuración actual para el tamaño de la página de respuesta.