Как кэшировать список запросов в представлениях Django?
Я хотел бы сохранить список "Последние просмотренные" 20 запросов в представлении Django. Также я хочу избежать создания отдельной модели для нее и просто хранить запрошенные URL-адреса в memcached, передавая каждый новый запрос в очередь фиксированного размера, а затем получая ее в представлениях. Но так как кеш - просто словарь ключ: значение, мне интересно, как лучше всего этого достичь?
1 ответ
Один из способов сделать это с помощью memcache - сохранить маринованный объект python как один ключ в кэше.
В этом случае мы могли бы использовать деку Python, которая имеет именно те свойства, которые мы хотели бы для списка из 20 самых последних элементов
Каждый раз, когда мы записываем новый просмотр страницы, нам нужно обновлять deque, то есть получать, открывать, добавлять, выбирать и возвращать новое значение в memcache.
К счастью, структура кэша Django будет обрабатывать и обрабатывать данные. Однако одна вещь, о которой нам нужно позаботиться, - это возможность состояния гонки - иными словами, если другой процесс также обновляет деку после того, как мы получим нашу копию и до того, как у нас появится возможность вернуть ее в кэш.
По этой причине мы должны использовать функцию 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',
)