Reactoo
Reactoo

Reputation: 1042

How to add get_queryset function in apiview of Django rest framework?

I am using Django APIView to include all my CRUD operation in a single api endpoint. But later on I had to use filtering logic based on the query parameters that have been passed. Hence I found it difficult to include it in a get api of APIView and made a separate api using generic view, ListAPiview.

Here is the view:

class LeadsView(APIView):
    permission_classes = [IsAuthenticated]

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

        id = pk
        if id is not None:
            abc = Lead.objects.get(id=id)
            serializer = LeadSerializer(abc)
            return serializer.data

    def post(self,request,*args,**kwargs):
        abc = LeadSerializer(data=request.data,many=True)
        if abc.is_valid():
            abc.save()
            return Response(abc.data, status=status.HTTP_201_CREATED)
        return Response(abc._errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request,pk, *args, **kwargs):

Now, I have to use filter class and also some custom filtering logic, I need to use get_queryset. Hence I have to create another api just for get method which I dont want.

class LeadAPIView(ListAPIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    queryset = Lead.objects.all().order_by('-date_created')
    serializer_class = LeadSerializer
    filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
    pagination_class = CustomPagination
    # filterset_fields = [ 'email','first_name','last_name','phone']
    filterset_class = LeadsFilter

    def get_queryset(self):
        source = self.request.GET.get("source", None)    #     
        lead_status = self.request.GET.get("lead_status", None)
        if source is not None:
            source_values = source.split(",")
            if lead_status is not None:
                lead_status_values= lead_status.split(",")
                return Lead.objects.filter(source__in=source_values,lead_status__in=lead_status_values)
            else:
                return Lead.objects.filter(source__in=source_values)
        elif lead_status is not None:
            lead_status_values = lead_status.split(",")
            if source is not None:
                source_values = source.split(",")
                return Lead.objects.filter(lead_status__in=lead_status_values,source__in=source_values)
            else:
                return Lead.objects.filter(lead_status__in=lead_status_values)

        return Lead.objects.all()

My question is, can I use get_queryset in the APIView instead of making another api?? Also, if I can use it, I assume I cant import filterset_class = LeadsFilter and also pagination? What will be the best approach??

My urls:

path('leads', LeadAPIView.as_view(), name='leads'),
path('lead', LeadsView.as_view(), name='leads-create'),
path('lead/<int:pk>', LeadsView.as_view()),

Upvotes: 0

Views: 2243

Answers (1)

nilay shah
nilay shah

Reputation: 61

APIView stands for MVT framework. There are 2 types of cases.

  1. If you want to return response to your django templates, you use views.
  2. In cases of returning json, xml (in short response) objects, you use viewset terminology. Viewsets supports filter-class, pagination-class, serialization, queryset, (custom mixins and many more).

p.s. in viewset if you wanted to overwrite default queryset, you define get_queryset method. Views don't support this. Also please check for @action decorators in django.

Upvotes: 2

Related Questions