如何在Pyramid中使用beaker缓存?

9 投票
5 回答
5544 浏览
提问于 2025-04-16 12:07

我在我的 ini 文件里有以下内容:

cache.regions = default_term, second, short_term, long_term
cache.type = memory
cache.second.expire = 1
cache.short_term.expire = 60
cache.default_term.expire = 300
cache.long_term.expire = 3600

在我的 __init__.py 文件里有这些:

from pyramid_beaker import set_cache_regions_from_settings
set_cache_regions_from_settings(settings)

不过,我不太确定怎么在我的视图或处理程序里真正实现缓存。有没有什么装饰器可以用?我本以为在 response 的API里会有相关的东西,但只有 cache_control 可用——它只是告诉用户去缓存数据,而不是在服务器端进行缓存。

有什么想法吗?

5 个回答

4

你应该使用缓存区域:

from beaker.cache import cache_region

@cache_region('default_term')
def your_func():
    ...
6

顺便说一下,调用 view_callable(request) 时它没能正常工作是因为,函数的参数会被转成一种特殊的格式存储起来,以便以后在缓存中查找。由于“self”和“request”在每次请求时都会变化,所以返回的值确实被缓存了,但却无法再次查找。这样一来,你的缓存就会堆满很多没用的键。

我通过在 view-callable 里面定义一个新函数来缓存我的视图函数的一部分,像这样:

    def view_callable(self, context, request):

        @cache_region('long_term', 'some-unique-key-for-this-call_%s' % (request.params['some-specific-id']))
        def func_to_cache():
            # do something expensive with request.db for example
            return something
        return func_to_cache()

到目前为止,这样做似乎效果不错……

谢谢!

12

我犯的错误是把装饰器函数@cache_region用在了一个视图调用上。虽然没有报错,但实际上并没有进行缓存。所以在我的views.py文件里,我尝试了这样:

@cache_region('long_term')
def photos_view(request):
    #just an example of a costly call from Google Picasa
    gd_client = gdata.photos.service.PhotosService()
    photos = gd_client.GetFeed('...')
    return {
        'photos': photos.entry
    }

没有错误,也没有缓存。而且你的视图调用会开始需要一个额外的参数!不过这样做是有效的:

#make a separate function and cache it
@cache_region('long_term')
def get_photos():
    gd_client = gdata.photos.service.PhotosService()
    photos = gd_client.GetFeed('...')
    return photos.entry

然后在视图调用里只需要:

def photos_view(request):
    return {
        'photos': get_photos()
    }

同样的道理适用于其他的@cache.cache等等。

总结一下:不要尝试缓存视图调用

附注:我还是有点怀疑视图调用是可以被缓存的 :)

更新:正如hlv后来解释的,当你缓存一个视图调用时,缓存实际上是从来没有被使用,因为@cache_region使用了调用的request参数作为缓存的标识。而request对于每个请求都是唯一的。

撰写回答