5👍
✅
First move the response data out into it’s own function because you will be using it twice. A better solution would be to create a serializer for the action.
def get_response_data(paginated_queryset):
data = {
'id_interface': interface.id_interface,
'id_EquipoOrigen': interface.id_EquipoOrigen_id,
'EquipoOrigen': interface.id_EquipoOrigen.nombre,
'LocalidadOrigen': interface.id_EquipoOrigen.localidad,
'CategoriaOrigen': interface.id_EquipoOrigen.categoria,
'id_PuertoOrigen': interface.id_PuertoOrigen_id,
'PuertoOrigen': interface.id_PuertoOrigen.nombre,
'estatus': interface.estatus,
'etiqueta_prtg': interface.etiqueta_prtg,
'grupo': interface.grupo,
'if_index': interface.if_index,
'bw': interface.bw,
'bw_al': interface.bw_al,
'id_prtg': interface.id_prtg,
'ospf': interface.ospf,
'description': interface.description,
'id_EquipoDestino': interface.id_EquipoDestino_id,
'EquipoDestino': interface.id_EquipoDestino.nombre,
'LocalidadDestino': interface.id_EquipoDestino.localidad,
'CategoriaDestino': interface.id_EquipoDestino.categoria,
'id_PuertoDestino': interface.id_PuertoDestino_id,
'PuertoDestino': interface.id_PuertoDestino.nombre,
'ultima_actualizacion': interface.ultima_actualizacion,
} for interface in queryset
return data
Then you would paginate in the same way as in rest framework’s built in mixins.ListModelMixin
.
@action(methods=['get'],detail=False,url_path='registros-data-table',url_name='registros_data_table')
def registros_data_table(self, request):
queryset = Interfaces.objects.all()
page = self.paginate_queryset(queryset)
if page is not None:
data = self.get_response_data(page)
return self.get_paginated_response(data)
data = self.get_response_data(queryset)
return Response(data)
24👍
Similar to how you would do it for list(...)
for ModelViewSets.
rest_framework.viewsets/ModelViewSet.html#list
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)
It would just be
class InterfacesViewSet(viewsets.ModelViewSet):
queryset=Interfaces.objects.all()
serializer_class=InterfaceSerializer
pagination_class=PostPageNumberPagination
@action(methods=['get'],detail=False,url_path='registros-data-table',url_name='registros_data_table')
def registros_data_table(self, request):
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)
Output would look like
{
"count": 1023
"next": "https://api.example.org/accounts/?page=5",
"previous": "https://api.example.org/accounts/?page=3",
"results": [
…
]
}
This is something I am using myself as a mixin for paginated responses.
Throw this guy on anything with a GenericViewSet.
class PaginatedResponseMixin(object):
def paginated_response(self, queryset=[], serializer_class=None, pagination_class=None,
context={}, **kwargs):
context['request'] = self.request
queryset = queryset or self.queryset
pagination_class = pagination_class or self.pagination_class
paginator = pagination_class()
serializer_class = serializer_class or self.get_serializer_class()
for k, v in kwargs.items():
setattr(paginator, k, v)
page = paginator.paginate_queryset(queryset, self.request, view=self)
serializer = serializer_class(page, context=context, many=True)
return paginator.get_paginated_response(serializer.data)
kwargs uses drf argument for the paginator.
Use like
class PostViewSet(PaginatedResponseMixin, viewsets.ModelViewSet):
queryset = ...
serializer = ...
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
return self.paginated_response(queryset, self.get_serializer_class(), CursorPagination, page_size=4)
return self.paginated_response() # takes default from ViewSet
return self.paginated_response(page_size=4) # takes partial arguments
1👍
Adding to other solutions if they did not work, if you want pagination to appear always instead of only when num items < size of page you could use.
def registros_data_table(self, request):
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(page, many=True)
return self.get_paginated_response(serializer.data)
- Django DEBUG=False still runs in debug mode
- Celery – minimize memory consumption
- How to override template in django-allauth?
- Using APITestCase with django-rest-framework
- Django templates stripping spaces?
Source:stackexchange.com