Django中的cache.fetch?

2 投票
3 回答
746 浏览
提问于 2025-04-15 18:58

Django的缓存有没有类似于Rails中cache.fetch的方法? (http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html#M001023)

cache.fetch("my_key") {
  // return what I want to put in my_key if it is empty
  "some_value"
}

Rails的缓存fetch方法的工作原理是这样的:

它的好处在于,它会先检查缓存,如果缓存里有值,就直接返回这个值。如果没有,它会把“some_value”存到缓存里,然后返回“some_value”。

在Django中有没有类似的功能?如果没有的话,如果我想自己实现这样一个功能,Python的语法应该是什么样的呢?

3 个回答

0

如果你想要在某个键不存在时获取一个默认值,可以提供第二个参数:

cache.get('key', 'default')

cache.get() 方法可以接受一个默认值参数。如果缓存中没有这个对象,就会返回这个默认值。

如果你希望在键不存在时把默认值保存到缓存中,可以使用你自己的自定义缓存后端。比如,这个例子扩展了 db 缓存后端(其他后端也可以这样用):

from django.core.cache.backends import db

class CustomCache(db.CacheClass):

    def get(self, key, default=None):
        result = super(CustomCache, self).get(key, default)

        if result == default:
            self.add(key, default)
            return default

        return result

不过我觉得这样做没有太大意义。

更新:
针对另一个帖子中的评论:是的,它会比较默认值和返回的值,如果两者相等,默认值就会被添加到缓存中。但是 cache.add 只有在键已经存在于缓存中时,才会设置新值(与 cache.set 不同,后者总是会覆盖原有值):

如果你想要仅在键不存在时添加一个键,可以使用add() 方法。这个方法的参数和 set() 一样,但如果指定的键已经存在,它不会尝试更新缓存

2

Julian的代码挺不错的,但它不支持位置参数(比如你想用sorted()的时候)。这是我修改后的版本:

def get_value(param1,param2):
    return "value %s - %s " % (str(param1),str(param2))

def fetch(key,val_function, *args, **kwargs)
    val = cache.get(key)
    if not val:
        val = val_function(*args, **kwargs)
        cache.set(key,val)
    return val
4

我觉得你需要写的代码大概是这样的:(编辑过)

def get_value(param1,param2):
    return "value %s - %s " % (str(param1),str(param2))

def fetch(key,val_function,**kwargs)
    val = cache.get(key)
    if not val:
        val = val_function(**kwargs)
        cache.set(key,val)
    return val

然后你可以这样来调用它:

fetch('key',get_value,param1='first',param2='second')

撰写回答