Per-request cache in Django?

前端 未结 7 1350
余生分开走
余生分开走 2020-12-08 11:39

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

7条回答
  •  没有蜡笔的小新
    2020-12-08 12:25

    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.

提交回复
热议问题