I would like to implement a decorator that provides per-request caching to any method, not just views. Here is an example use case.
I have a custom ta
Answer given by @href_ is great.
Just in case you want something shorter that could also potentially do the trick:
from django.utils.lru_cache import lru_cache
def cached_call(func, *args, **kwargs):
"""Very basic temporary cache, will cache results
for average of 1.5 sec and no more then 3 sec"""
return _cached_call(int(time.time() / 3), func, *args, **kwargs)
@lru_cache(maxsize=100)
def _cached_call(time, func, *args, **kwargs):
return func(*args, **kwargs)
Then get favourites calling it like this:
favourites = cached_call(get_favourites, request.user)
This method makes use of lru cache and combining it with timestamp we make sure that cache doesn't hold anything for longer then few seconds. If you need to call costly function several times in short period of time this solves the problem.
It is not a perfect way to invalidate cache, because occasionally it will miss on very recent data: int(..2.99.. / 3) followed by int(..3.00..) / 3). Despite this drawback it still can be very effective in majority of hits.
Also as a bonus you can use it outside request/response cycles, for example celery tasks or management command jobs.