web-dev-qa-db-ja.com

Djangoのpage_cacheデコレータを使用するときにキャッシュ全体をクリアする方法

_page_cache_デコレータを使用している非常にシンプルなサイトがあります。新しいデータをチェックし、利用可能であれば処理するcronjobがあります。 (これは、crontabで実行される管理コマンドを使用して実行されます)

次に、新しいデータが処理されたときにすべてのページキャッシュをクリアします。

私はここでドキュメントを見ています: https://docs.djangoproject.com/en/dev/topics/cache/?from=olddocs?from=olddocs

そして、cache.clear()を見つけました。これは私が望むものです。データ処理部分にフラグを追加し、新しいデータが見つかったときにcache.clear()を実行しました。

ただし、コマンドの実行後、キャッシュはクリアされません。 (ブラウザのキャッシュをクリアし、ブラウザではないことを確認しました)

cache.clear()は、キャッシュされたすべてのページをクリアするために機能しませんか?

DatabaseCacheを使用しているので、手動でキャッシュテーブルにアクセスしてクリアできますが、より良い方法はありますか?

23
monkut

SQLiteデータベースキャッシュでこの問題が発生しました-clear()メソッドは、MySQLデータベースキャッシュでは正常に動作しますが、キャッシュをクリアしません。 _DELETE from [table]_ステートメントの実行後、SQLiteキャッシュはDjango.db.transation.commit_unless_managed()の呼び出しを必要とするようです。

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')
_

怠zyでハードコーディングするよりも、_settings.CACHES_および_Django.db.router_から値を取得するのは非常に簡単です。

23
Colonel Sponsz

これはバグです #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)

これにより、トランザクションが確実にコミットされます。

5
Bran Handley

キャッシュに何かを入れてから、_manage.py Shell_コンソールからcache.clear()を呼び出してから、データベースキャッシュの内容を手動で確認してください。それが機能する場合、新しいデータが見つかったときにcache.clear()が呼び出されない可能性があります。

内部で何が起こっているのかを理解する最も簡単な方法は、import pdb; pdb.set_trace()関数の先頭にcache.clear()を配置し、デバッグサーバーを実行して待機してから、この関数を呼び出すコードです。コードをステップごとに実行できるか、このfuncが期待どおりに呼び出されないことがわかります。

3