Истечь кэш представления в Django?

@cache_page decorator является потрясающим. Но для моего блога я хотел бы сохранить страницу в кэше, пока кто-то не комментирует сообщение. Это походит на прекрасную идею, как люди редко комментируют настолько остающийся страницы в memcached, в то время как никто не комментирует, было бы большим. Я думаю, что у кого-то, должно быть, была эта проблема прежде? И это отличается, чем кэширование на URL.

Таким образом, решение, о котором я думаю:

@cache_page( 60 * 15, "blog" );
def blog( request ) ...

И затем я сохранил бы список всех ключей кэша используемым для представления блога и затем имел бы способ, истекают пространство кэша "блога". Но я супер не испытан с Django, таким образом, я задаюсь вопросом, знает ли кто-то лучший способ сделать это?

44
задан fifi finance 22 July 2016 в 22:54
поделиться

3 ответа

Это решение работает для версий 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: не тестировал это всесторонне, но пока что у меня все работает нормально.

44
ответ дан 26 November 2019 в 21:59
поделиться

Стратегия экспоненциального роста используется в STL и, похоже, работает нормально. Я бы сказал придерживаться этого по крайней мере до тех пор, пока вы не найдете определенный случай, когда это не сработает.

-121--1886467-

Для какой версии Oracle? 10g + поддерживает регексы - см. t его поток на форуме OTN Discussion о том, как использовать REGEXP_REPLACE для изменения непечатаемых символов на ".

-121--1317459-

Вместо использования декоратора страниц кэша можно вручную кэшировать объект записи блога (или подобное) если нет комментариев, а затем, когда есть первый комментарий, повторно кэшировать объект записи блога, чтобы он был актуальным (предполагая, что у объекта есть атрибуты, которые ссылаются на какие-либо комментарии), но тогда просто дайте этим кэшированным данным для комментированной записи блога истечь, и тогда не беспокойтесь о повторном кэшировании...

3
ответ дан 26 November 2019 в 21:59
поделиться

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 устанавливает для вас время истечения срока действия ключей кеша, но пользовательское удаление ключей кеша в нужное время является более сложной задачей.

7
ответ дан 26 November 2019 в 21:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: