-
-
Save dpnova/1223933 to your computer and use it in GitHub Desktop.
def expire_view_cache(view_name, args=[], namespace=None, key_prefix=None, method="GET"): | |
""" | |
This function allows you to invalidate any view-level cache. | |
view_name: view function you wish to invalidate or it's named url pattern | |
args: any arguments passed to the view function | |
namepace: optioal, if an application namespace is needed | |
key prefix: for the @cache_page decorator for the function (if any) | |
from: http://stackoverflow.com/questions/2268417/expire-a-view-cache-in-django | |
added: method to request to get the key generating properly | |
""" | |
from django.core.urlresolvers import reverse | |
from django.http import HttpRequest | |
from django.utils.cache import get_cache_key | |
from django.core.cache import cache | |
from django.conf import settings | |
# create a fake request object | |
request = HttpRequest() | |
request.method = method | |
if settings.USE_I18N: | |
request.LANGUAGE_CODE = settings.LANGUAGE_CODE | |
# Loookup the request path: | |
if namespace: | |
view_name = namespace + ":" + view_name | |
request.path = reverse(view_name, args=args) | |
# get cache key, expire if the cached item exists: | |
key = get_cache_key(request, key_prefix=key_prefix) | |
if key: | |
if cache.get(key): | |
cache.set(key, None, 0) | |
return True | |
return False |
Sounds like a good idea.. I recall there was some issue with language when I was originally looking at this. Any suggestions? :)
from django.conf import settings
request.LANGUAGE_CODE = settings.LANGUAGE_CODE
should do the trick (because the language is appended to the cache-key). I didn´t test with all caching-backends, but it works for me (db, memcached).
Thanks for that! Have updated and will give it a test :)
from the django-docs:
"If USE_I18N is set to True then the generated cache key will include the name of the active language. This allows you to easily cache multilingual sites without having to create the cache key yourself."
so maybe we should add this (just to make sure):
if settings.USE_I18N:
request.LANGUAGE_CODE = settings.LANGUAGE_CODE
That makes a lot of sense.. and now totally explains the weirdness I originally say. I think language code was being included unconditionally before and I removed that to get it working for me. Thanks a lot Patrick!
great. this function is simple and awesome – it totally saved my day/week. IMHO, this should be part of djangos core.
I cant get this to work with redis, my keys in the db are:
redis 127.0.0.1:6379[3]> keys *
1) ":1:views.decorators.cache.cache_page..GET.3ea110fe325fa79fc1c57f03f06bc7b4.d41d8cd98f00b204e9800998ecf8427e.es.Europe/Madrid"
2) ":1:views.decorators.cache.cache_header..3ea110fe325fa79fc1c57f03f06bc7b4.es.Europe/Madrid"
The get_cache_key returns nothing, im using other cache than default ([3]) called "users"
test in django==1.8.14, get_cache_key with request. require META["SERVER_NAME"] and META["SERVER_PORT"].
great! you may want to add request.LANGUAGE_CODE in order for this to work anything else than "en-us".