如何清除使用Django的page_cache装饰器时的整个缓存?
我有一个比较简单的网站,里面用到了 page_cache
这个装饰器。我设置了一个定时任务(cronjob),它会定期检查是否有新数据,如果有的话就处理这些数据。(这个任务是通过管理命令和 crontab 来执行的)
我想在处理完新数据后,清空所有的页面缓存。
我在这里查看了文档:https://docs.djangoproject.com/en/stable/topics/cache/
我发现了 cache.clear()
,看起来正是我需要的功能。我在数据处理的部分添加了一个标志,当找到新数据时就执行 cache.clear()
。
但是,命令执行后,缓存并没有被清空。(我已经清除了浏览器的缓存,确认不是浏览器的问题)
难道 cache.clear()
不能清除所有的缓存页面吗?
我使用的是 DatabaseCache
,所以我想我可以手动去清空缓存表,但有没有更好的方法呢?
4 个回答
先把一些东西放进缓存里,然后试着在 manage.py shell
控制台里调用 cache.clear()
,然后手动检查一下数据库里的缓存内容。如果这样能成功,那可能是因为你在找到新数据时没有调用 cache.clear()
。
想要更好地理解这个过程,可以在 cache.clear()
函数的开头加上 import pdb; pdb.set_trace()
,然后运行调试服务器,等着看。当有代码调用这个函数时,你就可以一步一步地执行它的代码,或者你会发现这个函数根本没有按你预期被调用。
这是一个错误,具体可以查看#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)
这段代码的作用就是确保事务被提交。
我遇到了一个关于SQLite数据库缓存的问题——虽然在MySQL数据库缓存中,clear()
方法可以正常清除缓存,但在SQLite中却不行。看起来在执行DELETE from [table]
语句后,需要调用django.db.transation.commit_unless_managed()
才能清除缓存。
在1.3版本之前,我就开始使用多个缓存了,当时还没有官方支持,所以我为一些缓存调用(包括clear()
)写了一个封装器,这样我就可以重写这个方法并加入commit_unless_managed()
。我觉得这可能应该记录为一个bug。
下面是我用来清空memcache缓存(在django.core.cache
中是默认缓存)和存储在settings.DATABASES['cache_database']
数据库的cache_table
中的数据库缓存的代码大纲。
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
中获取值,这样应该会简单很多。