'How to get data from post request in generics.ListAPIView DRF?

There is some view:

class Search(CategoryDetail):
serializer_class = ProductSerializer

def get_queryset(self):
    # print(self.request)
    return self.get_filters(None)

It inherits from another ListAPIView and does something.

From front on Vue.js throught post i pass some query parameter:

async Search(){
        axios
            .post('api/products/search', {'query': this.query})
            .then(response =>{
                this.products = response.data
            })
            .catch(error=>{
                console.log(error)
            })
    }

Initially, i performed work with this post request through the search view function:

@api_view(['POST'])
def search(request):
   query = request.data.get('query')

   if query:
       products = Product.objects.filter(Q(name__icontains=query) | Q(description__icontains = query))
       serializer = ProductSerializer(products, many=True)
       return Response(serializer.data)
   else:
       return Response({"products": []})

But now i need to change the view function to a class, but in the class i need to get the same query = request.data.get('query'), however, when i try, the Bad Request error is constantly returned.



Solution 1:[1]

ListAPIView doesn't accept post requests. You should pass your query as a GET request query parameter and reach it in the get_queryset method to filter your results.

class ProductList(generics.ListCreateAPIView):
    serializer_class = ProductSerializer

    def get_queryset(self):
        query = self.request.query_params.get('query')
        if query is not None:
            return Product.objects.filter(Q(name__icontains=query) | Q(description__icontains = query))
        else:
            Product.objects.none()

If you must use POST data and return the list of objects, you can implement your own APIView and use its post method.

class PrdocutList(APIView):
      def post(self, request, format=None):
        query = request.data.get('query')
        if query:
            products = Product.objects.filter(Q(name__icontains=query) | Q(description__icontains = query))
        else:
            products =  Product.objects.none()
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data)

You can also implement your own filter_backend.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nima Afshar