Как очистить весь кеш при использовании django page_cache decorator

У меня довольно простой сайт, где я использую декоратор page_cache. У меня есть cronjob, который проверяет наличие новых данных и обрабатывает его, если он доступен. (Это выполняется с использованием команд управления, выполняемых с помощью crontab)

Я хочу, чтобы затем очистить все кеши страниц при обработке новых данных.

Я смотрю документацию здесь: https://docs.djangoproject.com/en/dev/topics/cache/?from=olddocs?from=olddocs

и нашел cache.clear(), который, похоже, я хочу. Я добавил флаг в часть обработки данных и выполнил cache.clear() при обнаружении новых данных.

Однако после выполнения команды кеш не очищается. (Я очистил кеширование браузера и проверил, чтобы убедиться, что это не браузер)

Не работает ли cache.clear() для очистки всех кэшированных страниц?

Я использую DatabaseCache, поэтому, я думаю, я мог бы входить и очищать таблицу кеша вручную, но есть ли лучший способ?

Ответ 1

У меня была эта проблема с кешем базы данных SQLite - метод clear() не очищает кеш, хотя он отлично работает с кешем базы данных MySQL. Кажется, что кэш SQLite нуждается в вызове django.db.transation.commit_unless_managed() после выполнения оператора DELETE from [table].

Я использую несколько кешей, так как до официального добавления в ядро ​​как часть 1.3 и так обертка вокруг нескольких вызовов кеша - включая clear() - поэтому я смог переопределить этот метод и включить commit_unless_managed(). Я думаю, что я должен, вероятно, зарегистрировать его как ошибку.

Вот схема кода, который я использую, чтобы очистить кеш memcache (кеш по умолчанию в django.core.cache) и кэш базы данных, хранящийся в cache_table базы данных settings.DATABASES['cache_database'].

from django.db import connections, transaction
from django.core.cache import cache # This is the memcache cache.

def flush():
    # This works as advertised on the memcached cache:
    cache.clear()
    # This manually purges the SQLite cache:
    cursor = connections['cache_database'].cursor()
    cursor.execute('DELETE FROM cache_table')
    transaction.commit_unless_managed(using='cache_database')

Вместо того, чтобы быть ленивым и жестким кодированием, то, как у меня, должно быть довольно легко получить значения из settings.CACHES и django.db.router.

Ответ 2

Это ошибка # 19896, которая выглядит исправленной в 1.6.

Если вы используете более старую версию, выполняющую что-то вроде следующего, выполните ясную работу, как ожидалось.

from django.db import router, transaction


def clear_cache(the_cache):
    the_cache.clear()
    # commit the transaction
    db = router.db_for_write(the_cache.cache_model_class)
    transaction.commit_unless_managed(using=db)

Это только гарантирует, что транзакция будет совершена.

Ответ 3

Поместите что-то в кеш, затем попробуйте вызвать cache.clear() из консоли manage.py shell и затем вручную проверить содержимое кэша базы данных. Если это работает, возможно, ваш cache.clear() просто не вызывается при обнаружении новых данных.

Самый простой способ понять, что происходит под капотом, - это просто положить import pdb; pdb.set_trace() в начало функции cache.clear(), затем запустить сервер отладки и подождать, затем некоторый код вызовет эту функцию, вы сможете выполните пошаговый код, или вы просто увидите, что этот func не называется ожидаемым.