@cache_page decorator
является потрясающим. Но для моего блога я хотел бы сохранить страницу в кэше, пока кто-то не комментирует сообщение. Это походит на прекрасную идею, как люди редко комментируют настолько остающийся страницы в memcached, в то время как никто не комментирует, было бы большим. Я думаю, что у кого-то, должно быть, была эта проблема прежде? И это отличается, чем кэширование на URL.
Таким образом, решение, о котором я думаю:
@cache_page( 60 * 15, "blog" );
def blog( request ) ...
И затем я сохранил бы список всех ключей кэша используемым для представления блога и затем имел бы способ, истекают пространство кэша "блога". Но я супер не испытан с Django, таким образом, я задаюсь вопросом, знает ли кто-то лучший способ сделать это?
Это решение работает для версий django до 1.7
Вот решение, которое я написал, чтобы сделать то, о чем вы говорите, в некоторых из моих собственных проектов:
def expire_view_cache(view_name, args=[], namespace=None, key_prefix=None):
"""
This function allows you to invalidate any view-level cache.
view_name: view function you wish to invalidate or it's named url pattern
args: any arguments passed to the view function
namepace: optioal, if an application namespace is needed
key prefix: for the @cache_page decorator for the function (if any)
"""
from django.core.urlresolvers import reverse
from django.http import HttpRequest
from django.utils.cache import get_cache_key
from django.core.cache import cache
# create a fake request object
request = HttpRequest()
# Loookup the request path:
if namespace:
view_name = namespace + ":" + view_name
request.path = reverse(view_name, args=args)
# get cache key, expire if the cached item exists:
key = get_cache_key(request, key_prefix=key_prefix)
if key:
if cache.get(key):
# Delete the cache entry.
#
# Note that there is a possible race condition here, as another
# process / thread may have refreshed the cache between
# the call to cache.get() above, and the cache.set(key, None)
# below. This may lead to unexpected performance problems under
# severe load.
cache.set(key, None, 0)
return True
return False
Django использует эти кеши запроса представления, поэтому он создает фальшивый объект запроса для кэшированного представления, использует его для получения ключа кеша, а затем его срок действия истекает.
Чтобы использовать это так, как вы говорите, попробуйте что-нибудь вроде:
from django.db.models.signals import post_save
from blog.models import Entry
def invalidate_blog_index(sender, **kwargs):
expire_view_cache("blog")
post_save.connect(invalidate_portfolio_index, sender=Entry)
Итак, в основном, когда когда-либо сохраняется объект записи блога, вызывается invalidate_blog_index, и срок действия кэшированного представления истекает. NB: не тестировал это всесторонне, но пока что у меня все работает нормально.
Стратегия экспоненциального роста используется в STL и, похоже, работает нормально. Я бы сказал придерживаться этого по крайней мере до тех пор, пока вы не найдете определенный случай, когда это не сработает.
-121--1886467- Для какой версии Oracle? 10g + поддерживает регексы - см. t его поток на форуме OTN Discussion о том, как использовать REGEXP_REPLACE для изменения непечатаемых символов на "
.
Вместо использования декоратора страниц кэша можно вручную кэшировать объект записи блога (или подобное) если нет комментариев, а затем, когда есть первый комментарий, повторно кэшировать объект записи блога, чтобы он был актуальным (предполагая, что у объекта есть атрибуты, которые ссылаются на какие-либо комментарии), но тогда просто дайте этим кэшированным данным для комментированной записи блога истечь, и тогда не беспокойтесь о повторном кэшировании...
The cache_page декоратор будет использовать CacheMiddleware в конце, который сгенерирует ключ кеша на основе запроса (см. django.utils.cache.get_cache_key
) и key_prefix («блог» в вашем случае). Обратите внимание, что «блог» - это только префикс, а не весь ключ кеша.
Вы можете получить уведомление с помощью сигнала post_save django , когда комментарий сохранен, затем вы можете попытаться создать ключ кеша для соответствующей страницы (страниц) и, наконец, сказать cache.delete (key )
.
Однако для этого требуется cache_key, который создается на основе запроса ранее кэшированного представления. Этот объект запроса недоступен при сохранении комментария. Вы можете создать ключ кэша без соответствующего объекта запроса, но это построение происходит в функции, помеченной как закрытая ( _generate_cache_header_key
), поэтому вы не должны использовать эту функцию напрямую. Однако вы можете создать объект с таким же атрибутом пути, что и для исходного кэшированного представления, и Django этого не заметит, но я не рекомендую этого делать.
Декоратор cache_page немного абстрагирует кеширование для вас и затрудняет прямое удаление определенного объекта кеша. Вы можете создать свои собственные ключи и обрабатывать их таким же образом, но это требует дополнительного программирования и не так абстрактно, как декоратор cache_page
.
Вам также придется удалить несколько объектов кеша, если ваши комментарии отображаются в нескольких представлениях (т. Е. Индексная страница с подсчетом комментариев и отдельные страницы записей в блоге).
Подводя итоги: Django устанавливает для вас время истечения срока действия ключей кеша, но пользовательское удаление ключей кеша в нужное время является более сложной задачей.