Django Rest Framework ViewSet在重写list()方法时丢失了分页,SearchFilter和OrderingFilter

时间:2018-06-15 15:34:30

标签: python django django-rest-framework

我必须覆盖DRF ViewSet的默认list()方法,但是当我这样做时,所有过滤,排序和分页都会停止工作。

这是ViewSet的代码:

class ZoneViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = models.Zone.objects.all()
    serializer_class = serializers.ZoneSerializer
    filter_backends = (SearchFilter, OrderingFilter,)
    search_fields = ('city', 'name')

    def list(self, serializer, pk=None):
        if pk:
            queryset = models.Zone.objects.filter(city=pk)
        else:
            queryset = models.Zone.objects.all()
        serializer = serializers.ZoneSerializer(queryset, many=True, context={'request':self.request})
        return Response(serializer.data)

如何在不丢失此功能的情况下覆盖list()方法?

2 个答案:

答案 0 :(得分:1)

默认list()方法实现了所有这些功能。因此,不要覆盖list,而是覆盖get_queryset()方法。您可以使用self.kwargs['pk']获取pk值:

class ZoneViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = models.Zone.objects.all()
    serializer_class = serializers.ZoneSerializer
    filter_backends = (SearchFilter, OrderingFilter,)
    search_fields = ('city', 'name')

    def get_queryset(self):
        pk = self.kwargs['pk']
        if pk:
            queryset = models.Zone.objects.filter(city=pk)
        else:
            queryset = models.Zone.objects.all()

答案 1 :(得分:0)

接受的答案对我不起作用,因为我的清单查询集逻辑破坏了详细信息并删除了端点。相反,我粘贴了列表实现,并根据自己的需要调整了逻辑

class MyViewSet(viewsets.ModelViewSet):                                                                                
    permission_classes = (IsAuthenticated,)                                                                               
    serializer_class = MySerializer                                                                                    
    filter_fields = ["a_id", "b_id"]                                                                               

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

    def list(self, request):                      
        # my custom query set logic                                                                                   
        a = self.request.query_params.get("a_id", None)                                                              
        b = self.request.query_params.get("b_id", None)                                                          
        if a is None and b is None:                                                                                
            queryset = My.objects.none()                                                                               
        else:                                                                                                             
            queryset = My.objects.all()
        # end custom                                                                                

        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(serializer.data)   

请参见http://www.cdrf.co/3.9/rest_framework.viewsets/ModelViewSet.html