Reputation: 150
Context: I am facing an issue when caching through redis ModelViewSet
API view in Django REST framework (DRF) using method decorator cache_page
.
Docs reference: https://www.django-rest-framework.org/api-guide/caching/
Code Snippet: https://hastebin.com/apoqeloyav.py
Example Scenario
Here is the current behavior (tested manually using Swagger UI)
send GET request to /products endpoint -> this will request to my DRF server and cache the view
send GET request to /products endpoint again -> this will respond products data as cached data (as verified in dev tools network tab "Served from disk cache"). It also means that it didn't hit my DRF server to retrieve the data.
send PATCH request to /products/{product_id} endpoint -> this will update details then invalidate cache (Redis cache keys are now empty at this point)
send GET request to /products endpoint again -> This will still respond product data as cached data (verified because the updated data from doing step 3 is still not present). It also means that it didn't hit my DRF server to retrieve the data.
Here is my expected behavior (tested manually using Swagger UI)
How do I get the expected results so that if redis cache is empty, it should hit my DRF server to retrieve the latest data and cache the succeeding calls until its invalidated again? Also, I am not sure if this is an issue, or just a normal behavior.
Here is what I tried so far when invalidating the cached data from redis, but none of them works and still serves cached data
from disk cache
and does not hit my DRF API endpointHere are the version sI am using
Upvotes: 1
Views: 2876
Reputation: 7729
The request from 4. does not even hit the redis cache, because it returns a local cache (note the "From disk cache" in response code).
You should differentiate between a public cache (i.e. the server cache used by all users) and a private cache (the user's browser cache).
I think, when using cache_page
decorator, other than caching the request, it also sets "Cache-control" response headers to allow a private cache of the request. The browser uses those headers to cache the request locally, and return a local cached response until max-age
expires.
To prevent this behaviour, at the server level, you can use @never_cache
decorator, which sets Cache-control
response headers to prevent local caching, or use @cache_control(public=True)
to allow only public cache of the request (this also tweaks the cache control response headers accordingly).
More on Controlling cache.
Upvotes: 2