I struggled with a similar situation and here is the solution I came up with, I started it on an earlier version of Django but it is currently in use on version 2.0.3.
First issue: when you set things to be cached in Django, it sets headers so that downstream caches -- including the browser cache -- cache your page.
To override that, you need to set middleware. I cribbed this from elsewhere on StackOverflow, but can't find it at the moment. In appname/middleware.py
:
from django.utils.cache import add_never_cache_headers
class Disable(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
add_never_cache_headers(response)
return response
Then in settings.py
, to MIDDLEWARE
, add:
'appname.middleware.downstream_caching.Disable',
Keep in mind that this approach completely disables downstream caching, which may not be what you want.
Finally, I added to my views.py
:
def expire_page(request, path=None, query_string=None, method='GET'):
"""
:param request: "real" request, or at least one providing the same scheme, host, and port as what you want to expire
:param path: The path you want to expire, if not the path on the request
:param query_string: The query string you want to expire, as opposed to the path on the request
:param method: the HTTP method for the page, if not GET
:return: None
"""
if query_string is not None:
request.META['QUERY_STRING'] = query_string
if path is not None:
request.path = path
request.method = method
# get_raw_uri and method show, as of this writing, everything used in the cache key
# print('req uri: {} method: {}'.format(request.get_raw_uri(), request.method))
key = get_cache_key(request)
if key in cache:
cache.delete(key)
I didn't like having to pass in a request
object, but as of this writing, it provides the scheme/protocol, host, and port for the request, pretty much any request object for your site/app will do, as long as you pass in the path and query string.