AttributeError:''对象没有属性' page' DRF分页

时间:2016-07-11 07:44:51

标签: django pagination django-rest-framework

这是我2天前问的question。我用Louis Barranqueiro的answer解决了我的问题。  现在我想在序列化数据中添加当前页码和page_size。我知道我必须在PageNumberPagination类中自定义get_paginated_response方法,但是当我这样做时,我会收到此错误:

我的代码

 def get_paginated_response(self, data, request):
        # import pdb
        # pdb.set_trace()
        return Response(OrderedDict([
            ('next', self.get_next_link()),
            ('current', self.get_current_link()),
            ('previous', self.get_previous_link()),
            ('results', data)
        ]))

    def get_queryset(self, request):
        product_sync_ts = self.request.GET.get('product_sync_ts', None)
        if product_sync_ts:
            product = Product.objects.filter(....)
            )
            # return self.get_paginated_response(product, self.request)
            return Response(product)
        else:
            content = {'details': "Bad Request"}
            raise APIException400(request, content)


    def get(self, request, format=None):
        products = self.get_queryset(request)
        serializer = SyncedProductSerializer(instance={'products': products})
        # product = self.paginate_queryset(serializer, request)
        return self.get_paginated_response(serializer, request)
        # return self.get_paginated_response(serializer.data, request)

错误:

File "/Users/Documents/content-api/venv/lib/python2.7/site-packages/rest_framework/pagination.py", line 242, in get_next_link
    if not self.page.has_next()
AttributeError: 'PaginatedProductList' object has no attribute 'page'

5 个答案:

答案 0 :(得分:0)

所以最后我发现了如何解决这个问题。

下面是代码(我正在做的简单和愚蠢的错误)

class PaginatedProductList(APIView, PageNumberPagination):

    page_size = 1000 #---crucial line
    max_page_size = 1000

    def get_paginated_response(self, data, page, page_num):
        return Response(OrderedDict([
            ('count', self.page.paginator.count),
            ('current', page),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('page_size', page_num),
            ('results', data)
        ]))

    def get_queryset(self, request):
        product_sync_ts = self.request.GET.get('product_sync_ts', None)
        if product_sync_ts:
            product = Product.objects.filter(...)
            )
            return self.paginate_queryset(product, self.request)

        raise APIException400(request, {'details': "Bad Request"})

    def get(self, request):
        page = self.request.GET.get('page', 1)
        page_size = self.request.GET.get('page_size', 1000)
        products = self.get_queryset(request)
        serializer = SyncedProductSerializer(instance={'products': products})
        return self.get_paginated_response(serializer.data, page, page_size)

答案 1 :(得分:0)

有些人可能想尝试:

REST_FRAMEWORK = {
    'PAGE_SIZE': 20,
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',}

在settings.py

带有像

这样的视图
class GeneralManagementAPIView(generics.ListAPIView):
    queryset = GeneralManagements.objects.all()
    permission_classes = (IsAuthenticatedOrReadOnly,)
    renderer_classes = (GeneralManagementJSONRenderer,)
    serializer_class = GeneralManagementSerializer

    def get_queryset(self):
        return GeneralManagements.objects.all()

    def list(self, request):
        queryset = self.get_queryset()
        page = self.paginate_queryset(queryset)
        print("request ", request)

        serializer_context = {'request': request}
        serializer = self.serializer_class(
            page, context=serializer_context, many=True
        )
        print("serializer ", serializer, "serializer.data", serializer.data )
        return self.get_paginated_response(serializer.data)

答案 2 :(得分:0)

除了在视图中继承PageNumberPagination类之外,尝试在视图之外定义您的分页类(作为单独的类)继承自PageNumberPagination。并将该类名称称为pagination class = YourClassName。在您的视图中

class PaginationClass(PageNumberPagination):
     page_size = 2

并且在视野中,

class GeneralManagementAPIView(generics.ListAPIView):
     pagination_class = PaginationClass

答案 3 :(得分:0)

我只是添加我的答案,以帮助其他面临相同问题的用户。 除了上面的陈述,它还以一种更简单的方式解决了您的问题。

只需传递 PageNumberPagination 并在 self.paginate_queryset 方法中添加请求

class PaginatedProductList(APIView, PageNumberPagination):

def get(self, request):
        products = Product.objects.filter(....)
        return self.paginate_queryset(products, request) 

答案 4 :(得分:0)

您应先致电paginate_queryset,然后再致电get_paginated_response

  

请注意,paginate_queryset方法可能会在分页实例上设置状态,以后可以由get_paginated_response方法使用。

https://www.django-rest-framework.org/api-guide/pagination/