如何在使用Django的page_cache装饰器时清除整个缓存?

35
我有一个相当简单的网站,我在其中使用了page_cache装饰器。 我有一个cron作业,用于检查是否有新数据并在可用时处理它。 (这是使用crontab执行的管理命令运行的)
当处理新数据时,我想清除所有页面缓存。
我在这里查看文档: https://docs.djangoproject.com/en/stable/topics/cache/ 找到了cache.clear(),似乎是我想要的。 我在数据处理部分添加了一个标志,并在发现新数据时执行cache.clear()
然而,命令运行后缓存并没有被清除。 (我已经清除了浏览器缓存并确保不是浏览器的问题) cache.clear()不能清除所有缓存页面吗?
我正在使用DatabaseCache,所以我猜我可以手动进入并清除缓存表,但是否有更好的方法?
4个回答

32
我在使用 SQLite 数据库缓存时遇到了问题 - clear() 方法不清除缓存,但在使用 MySQL 数据库缓存时表现正常。似乎在运行 DELETE from [table] 语句后需要调用 django.db.transation.commit_unless_managed() 来清空 SQLite 缓存。
在 Django 核心部分中添加官方支持之前,我一直在使用多个缓存,并且有一个包装器围绕着几个缓存调用 - 包括 clear() - 所以我能够覆盖此方法并包含 commit_unless_managed()。我认为我应该将其记录为错误日志。
下面是我用于刷新 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.CACHESdjango.db.router 中获取值应该很容易。

2
我在这里犯了一个新手错误:cache.clear() 确实起作用,但浏览器会显示本地缓存的版本。当你调试此功能时,请务必强制执行正确的页面刷新。 - Oliver Zendel
在FF中需要在网络选项卡中显式设置禁用缓存。 - Voilin

6

这是一个错误#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)

这只是确保交易得到提交。


4
将某些内容放入缓存,然后尝试从manage.py shell控制台调用cache.clear()并手动检查数据库缓存内容。如果可以正常工作,那么可能是在发现新数据时没有调用cache.clear()
最简单的方法是在cache.clear()函数的开头添加import pdb; pdb.set_trace(),然后运行调试服务器并等待代码调用该函数,您将能够逐步执行其代码或者您会发现该函数未按您预期的方式被调用。

我已经使用shell进行了检查,即使我从shell运行cache.clear(),它似乎也无法清除缓存。但是,根据配置的过期时间,它似乎被清除了... - monkut
数据库缓存后端的clear方法非常简单:https://code.djangoproject.com/browser/django/tags/releases/1.3/django/core/cache/backends/db.py#L138 它只是从缓存表中删除所有记录。您确定您的缓存已正确配置吗?也许您使用了memcached或其他东西?另一个原因可能是浏览器缓存,为确保您可以在尚未使用过的其他浏览器中打开您的网站以查看该网站。 - Stack Exchange User

0

您可以使用自定义命令清除缓存(删除所有缓存值)。* 我使用的是 Django 默认情况下使用的 LocMemCache

例如,按照下面的方式在 core/management/commands/ 中创建 clearcache.py。* 不要忘记将 __init__.py 放置在 managementcommands 文件夹中,该文档 解释了如何在 Django 中创建自定义命令:

django-project
 |-core
 |  |-settings.py
 |  └-management
 |     |-__init__.py
 |     └-commands
 |        |-__init__.py
 |        └-clearcache.py # Here
 |-my_app1
 └-my_app2

因为你将clearcache.py放在core文件夹中,而settings.py也在那里,所以你需要将'core'设置为INSTALLED_APPS,否则Django无法识别自定义命令。
# "core/settings.py"

INSTALLED_APPS = [
    ...
    'core', # Here
    ...
]

然后,在core/management/commands/clearcache.py中创建一个继承BaseCommand类的Command类,如下所示:
# "core/management/commands/clearcache.py"

from django.core.management.base import BaseCommand
from django.core.cache import cache

class Command(BaseCommand):
    def handle(self, *args, **kwargs):
        cache.clear()
        self.stdout.write('Cache is cleared\n')

最后,运行以下命令可以清除缓存:

$ python manage.py clearcache
Cache is cleared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接