update modelserializer method framework create python django pagination django-rest-framework

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:

  1. 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)

  2. Haga que su viewset extienda esa mezcla y anule el método list() de ModelViewSet :

    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.