django - Django中的每个请求缓存?

标签 django django-cache

我想实现一个装饰器,为任何方法提供每个请求的缓存,而不仅仅是 View 。这是一个示例用例。

I have a custom tag that determines if a record in a long list of records is a "favorite". In order to check if an item is a favorite, you have to query the database. Ideally, you would perform one query to get all the favorites, and then just check that cached list against each record.

One solution is to get all the favorites in the view, and then pass that set into the template, and then into each tag call.

Alternatively, the tag itself could perform the query itself, but only the first time it's called. Then the results could be cached for subsequent calls. The upside is that you can use this tag from any template, on any view, without alerting the view.

In the existing caching mechanism, you could just cache the result for 50ms, and assume that would correlate to the current request. I want to make that correlation reliable.



这是我目前拥有的标签的示例。
@register.filter()
def is_favorite(record, request):

    if "get_favorites" in request.POST:
        favorites = request.POST["get_favorites"]
    else:

        favorites = get_favorites(request.user)

        post = request.POST.copy()
        post["get_favorites"] = favorites
        request.POST = post

    return record in favorites

有没有办法从 Django 获取当前请求对象,而无需传递它?从标签中,我可以只传递请求,该请求将始终存在。但我想从其他功能中使用这个装饰器。

是否存在按请求缓存的现有实现?

最佳答案

使用自定义中间件,您可以获得保证为每个请求清除的 Django 缓存实例。

这是我在一个项目中使用的:

from threading import currentThread
from django.core.cache.backends.locmem import LocMemCache

_request_cache = {}
_installed_middleware = False

def get_request_cache():
    assert _installed_middleware, 'RequestCacheMiddleware not loaded'
    return _request_cache[currentThread()]

# LocMemCache is a threadsafe local memory cache
class RequestCache(LocMemCache):
    def __init__(self):
        name = 'locmemcache@%i' % hash(currentThread())
        params = dict()
        super(RequestCache, self).__init__(name, params)

class RequestCacheMiddleware(object):
    def __init__(self):
        global _installed_middleware
        _installed_middleware = True

    def process_request(self, request):
        cache = _request_cache.get(currentThread()) or RequestCache()
        _request_cache[currentThread()] = cache

        cache.clear()

要使用中间件,请在 settings.py 中注册,例如:
MIDDLEWARE_CLASSES = (
    ...
    'myapp.request_cache.RequestCacheMiddleware'
)

然后,您可以按如下方式使用缓存:
from myapp.request_cache import get_request_cache

cache = get_request_cache()

有关更多信息,请参阅 django 低级缓存 api 文档:

Django Low-Level Cache API

修改 memoize 装饰器以使用请求缓存应该很容易。查看 Python 装饰器库,了解 memoize 装饰器的一个很好的示例:

Python Decorator Library

关于django - Django中的每个请求缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3151469/

相关文章:

python - Django - 'ContactForm' 对象没有属性 'get'

django - REST 请求将协商哪个 `format`?

Django 缓存框架。 TIMEOUT 和 CACHE_MIDDLEWARE_SECONDS 有什么区别?

django - 如何调整Django textarea的大小?

django - 如何在表单字段旁边添加自定义按钮或链接

python - Redis Python - 如何在python中根据特定模式删除所有键,无需python迭代

django - django 上的 memcache 不起作用

python - 在 Django 应用程序中实现 memcached 需要哪些步骤?

python - Django cache_page - 预填充/预缓存

python - 如何获取独立的 python 脚本来从我的 django 应用程序获取数据?