Django缓存获得过期条目

时间:2013-03-20 21:40:37

标签: django caching get

在我看来,我有以下

@require_POST
def loadVals(request):
  result = //do some heavy calculations
  return HttpResponse(json.dumps({"data": result}), content_type="application/json")

现在我添加了一个缓存,这样我就不必一直执行“重度计算”。所以新代码看起来像

settings.py

CACHES = {
'default': {
    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    'LOCATION': 'unique-snowflake'
}

}

views.py

from django.core.cache import get_cache

@require_POST
def loadVals(request):
  cache = get_cache('default')
  result = cache.get('res')
  if result == NONE:
    result = //do some heavy calculations
    cache.set('res', result, 30)
    return HttpResponse(json.dumps({"data": result}), content_type="application/json")
  else:
    return HttpResponse(json.dumps({"data": result}), content_type="application/json") 

我想要做的是,即使该缓存已过期,我也希望为前端用户节省一些等待时间(因为计算繁重)并且只返回最后一个过期的值。 然后刷新缓存。

我如何

1)获取过期缓存的值?因为如果缓存已过期,cache.get('res')将返回NONE

2)在返回HttpResponse语句之后进行调用以刷新缓存值并进行大量计算(返回statmenet只返回过期值)或者可以通过异步调用来执行此操作吗?

2 个答案:

答案 0 :(得分:2)

首先,您的代码存在一些语法问题。 其次,您无法从django缓存中获取过期值。过期的值一旦过期就会被删除,之后它们就不存在了。

如果您希望为这种情况存储更长的过期值,则需要将它们存储在数据库等更持久的存储中,而不是为此进行缓存。

或者您可以将结果缓存两次,其中一个更长,并从第二个缓存中提供:

from django.core.cache import get_cache

@require_POST
def loadVals(request):
    cache = get_cache('default')
    result = cache.get('res') or cache.get('res_long')
    if result is None:
        result = //do some heavy calculations
        cache.set('res', result, 30)
        cache.set('res_long', result, 60*60*24*7) # cache for a week
    return HttpResponse(json.dumps({"data": result}), content_type="application/json")

这仍然不是一个好方法,因为你仍然需要做一些事情来重新缓存短缓存。它也不是很好,因为你用双倍数据重载缓存后端。

如果您希望用户始终获得缓存内容,请尝试使用Celery将其与后台任务一起缓存。

答案 1 :(得分:0)

这对我有用:

1)创建一个全局变量,当你设置缓存时,也要设置这个全局变量。如果缓存已过期,则您的全局变量仍然存在过期值,因此请将其作为响应发送。并使用线程来更新缓存和全局变量。

2)使用python threading

import  threading
def loadVals():
    threading.Thread(group=None, target=methodToDoheavyCalculations).start()
    # return the expired cache in the meanwhile
    return HttpResponse(json.dumps(EXPIRED_VALUES), content_type="application/json")