Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将ListModelMixin与APIView组合以显示分页_Python_Django_Pagination_Django Rest Framework - Fatal编程技术网

Python 将ListModelMixin与APIView组合以显示分页

Python 将ListModelMixin与APIView组合以显示分页,python,django,pagination,django-rest-framework,Python,Django,Pagination,Django Rest Framework,我想在我的API中显示分页功能,我正在对多个序列化程序使用APIView。 我知道用ListView显示分页非常容易 我在某个地方看到,将ListModelMixin和APIView相结合是可行的,但如果我的代码如下所示: class ListModelMixin(object): def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset())

我想在我的API中显示分页功能,我正在对多个序列化程序使用
APIView

我知道用
ListView
显示分页非常容易
我在某个地方看到,将
ListModelMixin
APIView
相结合是可行的,但如果我的代码如下所示:

class ListModelMixin(object):
    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(serilaizer.data)

class ItemsAPIView(APIView):
    permission_classes = (permissions.IsAuthenticated,)
    pagination_class = api_settings.DEFAULT_PAGINATION_CLASS

    def get(self, request, format=None):
        """
        Return a list of all devices of this user.
        """
        reply = {}
        try:
            products = BaseItem.objects.owned_items().filter(owner=request.user)
            reply['data'] = OwnedItemSerializer(products, many=True).data

            items = BaseItem.objects.dev_items().filter(owner=request.user)
            reply['data'].extend(ItemSerializer(items, many=True).data)

        except:
            reply['data'] = []
        return Response(reply, status.HTTP_200_OK)
我如何组合它们,以便获得分页结果

提前谢谢

首先,你目前正在做的事情太复杂了,没有理由

为了实现“可分页”查询集,最好在简单的筛选器组合中更改
owned_items()
dev_items()
,而不是使用模型方法。举例说明:

products = BaseItem.objects.filter(owner=request.user, owned=True)
而不是

products = BaseItem.objects.owned_items().filter(owner=request.user)
这样,您就可以生成一个更容易分页的queryset:

user_items = BaseItem.objects.filter(
                 Q(owner=request.user, owned=True) |
                 Q(owner=request.user, dev=True)
             )
注1:如果您愿意,可以进一步简化,但这超出了您的问题范围。值得思考的是,请查看以下内容:

user_items =  BaseItem.objects.filter(owner=request.user).distinct()
注意2:您应该为单个模型使用单个序列化程序,因为您所做的工作增加了复杂性,但没有带来任何好处(高风险低回报情况)


在上述情况下,假设:

这里有一些方法可以实现您的目标:

  • 通过利用和,您可以重构类,使其具有自动分页的
    .list()
    方法:

    from rest_framework import mixins, generics
    
    class ItemsAPIView(mixins.ListModelMixin, generics.GenericAPIView,):
        permission_classes = (permissions.IsAuthenticated,)
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
        serializer_class = OwnedItemSerializer
    
        # You can define .get in here if you really need it.
        # You can also override .list to add specific functionality
    
  • 如果您不想使用上述方法,并且希望保留
    APIView
    ,则可以保留
    get
    方法并为其提供分页,如下所述:


  • 虽然我了解了您尝试执行的操作要点,但我建议
    ItemAPIView
    不要尝试以您目前的方式查询数据。视图应该提供
    queryset
    ,其余的应该由序列化程序完成。如果您可以提供您正在寻找的那种o/p以及
    序列化器
    定义,则可以发布一个明确的解决方案。我正在寻找的输出只是分页功能。如果我使用/api/v1/items?page=1,我每页应该有10个项目。使用的两个序列化程序是一个用于自有项目,另一个用于开发项目。@ShikharChauhan您了解两个序列化程序在我的情况下的用法吗?不,没有序列化程序代码很难判断。
    class ItemsAPIView(APIView):
        permission_classes = (permissions.IsAuthenticated,)
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
        serializer_class = MyNewUnifiedSerializerClass
    
        def get(self, request):
            user_items =  BaseItem.objects.filter(
                              owner=request.user
                          ).distinct()
            page = self.paginate_queryset(user_items)
    
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(user_items, many=True)
            return Response(serializer.data)
    
        # Now add the pagination handlers taken from 
        #  django-rest-framework/rest_framework/generics.py
    
        @property
        def paginator(self):
            """
            The paginator instance associated with the view, or `None`.
            """
            if not hasattr(self, '_paginator'):
                if self.pagination_class is None:
                    self._paginator = None
                else:
                    self._paginator = self.pagination_class()
                return self._paginator
    
         def paginate_queryset(self, queryset):
             """
             Return a single page of results, 
             or `None` if pagination is disabled.
             """
             if self.paginator is None:
                 return None
             return self.paginator.paginate_queryset(
                        queryset, 
                        self.request, 
                        view=self
                    )
    
         def get_paginated_response(self, data):
             """
             Return a paginated style `Response` object 
             for the given output data.
             """
             assert self.paginator is not None
             return self.paginator.get_paginated_response(data)