如何在 Django Rest Framework 中的操作中进行分页

Ces*_*sto 8 django django-rest-framework

下午好社区,我有一个关于 django rest 框架页面的问题,在这种情况下,我设法在视图集中做到了,但在集体行动中我未能实现。

附上 django rest 框架中答案的图片

在此处输入图片说明

行动

在此处输入图片说明

class PostPageNumberPagination(PageNumberPagination):
    page_size=10

class InterfacesViewSet(viewsets.ModelViewSet):

    queryset=Interfaces.objects.all()
    serializer_class=InterfaceSerializer
    pagination_class=PostPageNumberPagination

# La siguiente funcion es un decorador(funciones extra) de la clase RegistrosViewSet para poder manipular los datos que voy a presentar de acuerdo a la URL que se le asigne con el url_path
# El siguiente action actua para poder presentar todos los datos de todos los objetos
    @action(methods=['get'],detail=False,url_path='registros-data-table',url_name='registros_data_table')
    def registros_data_table(self, request):
            paginator=PostPageNumberPagination
            return Response(
                    {
                '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 Interfaces.objects.all()
            )
Run Code Online (Sandbox Code Playgroud)

更新:我使用了朋友@bdoubleu 提供的方法,但我发现对象没有被分页,也就是说在所有页面中出现的对象总数。

在此处输入图片说明

在此处输入图片说明

zye*_*eek 9

类似于您将如何list(...)为 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)
Run Code Online (Sandbox Code Playgroud)

它只是

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)
Run Code Online (Sandbox Code Playgroud)

输出看起来像

{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}
Run Code Online (Sandbox Code Playgroud)

这是我使用自己作为分页响应的混合的东西。把这个家伙扔到任何带有 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)
Run Code Online (Sandbox Code Playgroud)

kwargs使用 drf 参数作为分页器。

使用喜欢

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
Run Code Online (Sandbox Code Playgroud)


bdo*_*leu 5

首先将响应数据移到它自己的函数中,因为您将使用它两次。更好的解决方案是为该操作创建一个序列化器。

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
Run Code Online (Sandbox Code Playgroud)

然后,您将以与 Rest 框架内置的相同方式进行分页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)
Run Code Online (Sandbox Code Playgroud)