如何使用非orm模型进行自定义分页

时间:2017-03-03 20:28:16

标签: python django pagination django-rest-framework

我正在使用Django Rest Framework 3而且我遇到了一些问题。我在this example之后获得了自定义分页工作,并且我在this example之后得到了一个非工作模型。但是,我无法在非orm模型上获得自定义分页(或任何分页)。自定义分页在settings.py中设置为默认值,它适用于所有带模型的视图集。

具有模型的端点的JSON输出包括元信息并将对象嵌套在'对象中:'。没有模型的端点的JSON输出只给出了一个对象列表。我的代码发布在下面。关于如何使其发挥作用的任何想法?

自定义分页:

from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Response

class CustomPagination(LimitOffsetPagination):
    def get_paginated_response(self, data):       
        return Response({
            'meta': {
               'limit': self.get_limit(self.request),
               'next': self.get_next_link(),
               'offset': self.get_offset(self.request),
               'previous': self.get_previous_link(),
               'total_count': self.count
            },
            'objects': data
        })

对象:

class EMSEvent(object):
    def __init__(self, id, name, start, end):
        self.id = id
        self.name = name
        self.start = start
        self.end = end

串行:

class EMSEventSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()
    start = serializers.CharField()
    end = serializers.CharField()

    class Meta:
        fields = '__all__'

视图集:

class EMSEventViewSet(viewsets.ViewSet):
    serializer_class = EMSEventSerializer(many=True)
    http_method_names = ['get']


    def list(self, request):
        results = []
        """
        Here is code that opens up a SQL connection, executes a   
        query, then transfers the data into results
        """

        # Always sort results by start time
        results = sorted(results, key=lambda k: k.start)
        serializer = EMSEventSerializer(instance=results, many=True)

        return Response(serializer.data)

带有模型的API端点的JSON输出:

{
    meta: {
        limit: 20,
        next: "/api/v1/endpoint/?offset=20&limit=20&format=json",
        offset: 0,
        previous: null,
        total_count: 24
    },
    objects: [
        {
            description: "A Room",
            end: "2017-03-03T15:30:00",
            id: 1234,
            name: "Grad Day",
            resource_uri: "/api/v1/endpoint/1234/",
            room: "CMU Room",
            start: "2017-03-03T09:00:00"
        }
    ]    
}

没有模型的API端点的JSON输出

[
    {
        description: "A Room",
        end: "2017-03-03T15:30:00",
        id: 1234,
        name: "Graduate Day",
        resource_uri: "/api/v1/endpoint/1234/",
        room: "CMU Room",
        start: "2017-03-03T09:00:00"
    }
]

2 个答案:

答案 0 :(得分:0)

当您覆盖默认列表方法时,您必须自己对响应进行分页。在这种情况下,您list方法应该是这样的

def list(self, request):
    results = []
    """
    Here is code that opens up a SQL connection, executes a   
    query, then transfers the data into results
    """

    # Always sort results by start time
    results = sorted(results, key=lambda k: k.start)

    # if paginate_queryset is not accessible in ViewSet then you can import it from paginator itself.
    page = self.paginate_queryset(results)

    serializer = EMSEventSerializer(instance=results, many=True)
    return self.get_paginated_response(serializer.data)

答案 1 :(得分:0)

我通过修改Swapril Mahajan的答案来实现它:

class EMSEventViewSet(viewsets.GenericViewSet, CustomPagination):
    serializer_class = EMSEventSerializer(many=True)
    http_method_names = ['get']


    def list(self, request):
        results = []
        """
        Here is code that opens up a SQL connection, executes a   
        query, then transfers the data into results
        """

        # Always sort results by start time
        results = sorted(results, key=lambda k: k.start)
        page = self.paginate_queryset(results)
        serializer = EMSEventSerializer(instance=page, many=True)

        return self.get_paginated_response(serializer.data)

重大差异1:

class EMSEventViewSet(viewsets.GenericViewSet, CustomPagination):

我使用GenericViewSet而不是ViewSet。您必须使用ViewSet而不是ModelViewSet才能使其与非ORM数据源一起使用,并且显然需要GenericViewSet才能使用自定义分页。此外,您必须传递自定义分页。

重大差异2:

serializer = EMSEventSerializer(instance=page, many=True)

我将页面传递给序列化程序而不是结果。我实际上最终用instance = results测试它并得到了相同的结果,但是传入instance = page更有意义。