I’ve developed a Django site. There’s pretty much a 1-to-1 relationship between model instances in the dabatase, and pages on the site.
I’d like to cache each page on the site (using memcached as the cache back-end). The site isn’t too big — according to a back-of-an-envelope calculation, the whole thing should fit into a fairly small amount of RAM — and the data doesn’t change particularly frequently, so the entire site could effectively live in the cache.
However, when the data does change, I want the cache to reflect that immediately, so ideally I’d like each model instance to be able to clear its own page from the cache when saved.
The way I imagined I’d do that is to cache pages with their URL as the key. Then each model instance can use its URL (which it knows via get_absolue_url()) to clear its page from the cache.
Can I make Django’s per site caching mechanism use page URLs as the cache key?
I don’t know of any option to control the cache key, and the implementation in Django doesn’t suggest there is any. The code to generate the cache key for a request through the cache middleware lives in
django.utils.cache.get_cache_key(to know where to fetch from the cache) andlearn_cache_key(to know where to set the cache). You could monkey-patch these functions not to take headers into account like this:This will internally take an MD5 hash of the path, add a potential prefix, and also take the current locale (language) into account. You could further change it to omit the prefix and the language. I would not recommend using the plain path without hashing it, as memcached does not allow keys longer than 250 characters or containing whitespaces, according to the documentation. This should not be a problem because you can just apply
get_path_cache_keyto the URL fromget_absolute_url()as well and clear that page.