I try to cache ListAPIView.I find solution on stackoverflow:
from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page class ProductListAPIView(generics.ListAPIView): serializer_class = ProductSerializer @method_decorator(cache_page(60)) def dispatch(self, *args, **kwargs): return super(ProductListAPIView, self).dispatch(*args, **kwargs)
It works.
But in my project ,the client make GET request with timestamp, it will be cached , but other user can not hit this cache almost.
I try to remove timestamp, my code is:
class ProductListAPIView(generics.ListAPIView): serializer_class = ProductSerializer def dispatch(self, request, *args, **kwargs): key=gen_cache_key(request) print(key) res=cache.get(key) if res: return res res= super().dispatch(request, *args, **kwargs) cache.set(key,res,60) return res def gen_cache_key(request): params=request.GET key=request.path for x in params.lists(): if x[0]!='timestamp': key+=str(x[0]) key+=str(x[1][0]) return key
emmm. It raise an error. ContentNotRenderedError >> The response content must be rendered before it can be pickled.
How to deal with it ?
class DispatchMiddleware(MiddlewareMixin):
def process_response(self, request, response):
if hasattr(response, 'cache_key'):
key = response.cache_key
timeout=response.cache_time
del response.cache_key
del response.cache_time
cache.set(key,response,timeout)
return response
def dispatch(self, request, *args, **kwargs):
key = gen_cache_key(request)
res = cache.get(key)
if res:
return res
res = super().dispatch(request, *args, **kwargs)
res.cache_key = key
res.cache_time = 60 * 3
return res