如何在Django视图中缓存请求列表



我想把'Last Seen' 20个请求的列表保存到Django视图中。另外,我想避免为它创建一个单独的模型,只是将请求的url保存在memcached中,通过将每个新请求推送到固定大小的队列,然后在视图中检索队列。但由于缓存只是键:值字典,我想知道如何最好地实现这一点?

使用memcache实现此目的的一种方法是将pickle python对象作为单个键存储在缓存中。

在这种情况下,我们可以使用Python deque,它具有我们想要的包含最近20项的列表的属性

每次记录一个新的页面视图时,我们都需要更新deque,这意味着获取它,解pickle它,追加它,pickle它,并将新值设置回memcache。

幸运的是,Django的缓存框架会为我们处理pickle和unpickle。然而,我们需要注意的一件事是竞争条件的可能性——换句话说,如果在我们获得副本之后,在我们有机会将其设置回缓存之前,另一个进程也更新了deque。 由于这个原因,我们应该使用memcache的CAS('比较与设置')操作。这里有一个扩展的Django缓存后端,可以使用CAS:
https://github.com/anentropic/django-cas-cache

pip install django-cas-cache

我们将在自定义Django中间件中使用一些代码来更新每个页面视图的缓存,大致如下所示:

middleware.py

from collections import deque
from django.core.cache import cache
class LastSeenMiddleware(object):
    def process_response(request, response):
        # you might want some logic like this to only
        # record successful requests
        if response.status != 200:
            return response
        # in case we don't already have a deque, try to add
        # (add will not overwrite if key already exists)
        added = cache.add('last_seen', deque([request.path], maxlen=20))
        if not added:
            def update(val):
                val.append(request.path)
                return val
            cache.cas('last_seen', update)
        return response

views.py

from django.core.cache import cache
from django.shortcuts import render_to_response
def myview(request):
    last_seen = cache.get('last_seen')
    # whatever
    return render_to_response('mytemplate.html', {'last_seen': last_seen})

settings.py

CACHES = {
    'default': {
        'BACKEND': 'cascache.backends.memcached.MemcachedCASCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
# as a response processor, our middleware should probably come
# first in this list, in order to run *last*
MIDDLEWARE_CLASSES = (
    'myapp.middleware.LastSeenMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

相关内容

  • 没有找到相关文章

最新更新