【问题标题】:How to do custom pagination with non-orm model如何使用非 orm 模型进行自定义分页
【发布时间】:2017-07-24 02:18:23
【问题描述】:

我正在使用 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"
    }
]

【问题讨论】:

    标签: python django pagination django-rest-framework


    【解决方案1】:

    我通过修改 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 更有意义。

    【讨论】:

      【解决方案2】:

      当您覆盖默认列表方法时,您必须自己对响应进行分页。在那种情况下,你的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)
      

      【讨论】:

        猜你喜欢
        • 2013-04-29
        • 2016-04-15
        • 1970-01-01
        • 2017-08-31
        • 1970-01-01
        • 2012-08-28
        • 2012-04-02
        • 1970-01-01
        • 2021-07-17
        相关资源
        最近更新 更多