首页 > 解决方案 > 自定义分页在 Django rest 的 apiview 中不工作

问题描述

我在一个单独的文件中有一个自定义分页类,直到现在我一直将它导入 ListAPIView,但这次我尝试使用 APIView,但它没有用。

我的分页类:

class CustomPagination(PageNumberPagination):
    def get_paginated_response(self, data):
        return Response({
            'links': {
                'next': self.get_next_link(),
                'previous': self.get_previous_link()
            },
            'count': self.page.paginator.count,
            'page_size' : 15,
            'results': data
        })

我正在尝试使用自定义分页,因为我也可以计算对象的数量。

我尝试实现分页的观点:

from apps.products.api.pagination import CustomPagination

class CouponView(APIView):
    permission_classes = [AllowAny]
    #pagination_class = CustomPagination


    def get(self,request,pk = None,*args,**kwargs):

        id = pk
        if id is not None:
            abc = Coupons.objects.get(id=id)
            serializer = CouponSerializer(abc)
            return serializer.data
        else:
            abc = Coupons.objects.all()
            paginator = CustomPagination()
            result_page = paginator.paginate_queryset(abc, request)
            serializer = CouponSerializer(result_page,many=True)
            return Response (serializer.data,status=status.HTTP_200_OK)

标签: djangoapidjango-rest-frameworkdjango-viewsdjango-pagination

解决方案


APIView不支持此功能。您要么需要利用ListApiView或类似的泛型(例如RetrieveApiView),要么使用ReadOnlyModelViewSet。这些都支持分页,并为您提供get_object.

您的代码似乎正在实现基本的 ViewSet 功能(列表 + 检索)。API视图的问题在于这两个都使用get,因此它们不能组合成一个视图。使用视图集将解决这个问题。

class CouponReadOnly(ReadOnlyModelViewSet):
    pagination_class = SomeClass
    serializer_class = CouponSerializer
    queryset = Coupon.objects.all()

然后使用您的路由器将urls.py其链接起来,并让路由器生成路由。

# in your urls.py --------------
router = SimpleRouter()
router.register("coupons", CouponReadOnly, "coupon")

urlpatterns = [...] # existing routes
urlpatterns += router.urls

如果您想使用 2 个视图手动执行此操作,那么您可以使用泛型并手动创建路径,就像您已经是:

class CouponListView(ListAPIView):
    # you said this one already works

class CouponGetView(RetrieveAPIView):
    queryset = Coupon.objects.all()
    serializer_class = CouponSerializer


urlpatterns = [
    path("coupons/", CouponListView.as_view(), name="coupon-list"),
    path("coupons/<int:pk>", CouponGetView.as_view(), name="coupon-get"),
]
    

推荐阅读