2017-09-26 4 views
3

私はDjangoのビューごとに@cache_pageデコレータを使用しており、ビューごとに異なるkey_prefixを設定しています。特定のkey_prefixを持つDjango削除キャッシュ

私は、以前にキャッシュを削除した:

from django.core.cache import cache 
cache.clear() 

しかし、私はちょうど特定key_prefixを含むキーを削除するために何をしたい場合は?私は明らかにデータベースに接続してraw SQLを使って削除することでそれを行うことができますが、純粋なDjangoを使用できるかどうか疑問です。

私はメモリキャッシュではなく、データベースキャッシュを使用しています。

私はジャンゴ1.11とPython 3.6

+1

可能性のある重複した[Djangoのキャッシュから一致するすべてのキーを削除](HTTPSとしてsettings.pyを使用しました。com/questions/25292426/remove-all-matching-keys-django-cache) – lapinkoira

+0

@ lapinkoira、リンクありがとうございます。リンクされた質問の答えは、Djangoのlocalmemcacheでしか動作しないと述べています。私はDjangoのデータベースキャッシュを使用しています。私は解明する答えを更新しました。 – Wessi

+0

あなたの問題にこのリンクを使用することができます@Wessi。 https://drupal.stackexchange.com/questions/21434/how-do-i-clear-cache-using-an-sql-query –

答えて

3

前述の@ e4c5キャッシュは高速な処理に使用されているため、同じものに対してはredisを使用する必要があります。しかし、あなたの質問はデータベースに関するものなので、私は同じ答えをします。

Djangoにこれを行うための既存の機能はありません。しかし、Pythonの最良の部分は、簡単に新しい機能を追加するための猿のパスができます。以下は、私はあなたには、いくつかの場所にパッチコードの下に追加する必要がありprefix機能を取得するには

def index(request): 
    cache.set("name", "tarun") 
    cache.set("name_1", "tarun") 
    cache.set("name2", "tarun") 
    cache.set("name_4", "tarun") 
    cache.set("nam", "tarun") 

    cache.clear(prefix="name") 
    nam = cache.get("nam") 
    name_4 = cache.get("name_4", default="deleted") 
    return HttpResponse("Hello, world. nam={nam}, name_4={name_4}".format(nam=nam, name_4=name_4)) 

Patched

をテスト要求が作成されます。 // stackoverflowの:私はこのような

original_clear = None 


def patch_clear(): 
    from django.db import connections, router 
    from django.core.cache.backends.db import DatabaseCache 

    def __clear(self, prefix=None, version=None): 
     db = router.db_for_write(self.cache_model_class) 
     connection = connections[db] 
     table = connection.ops.quote_name(self._table) 
     with connection.cursor() as cursor: 
      if prefix is None: 
       cursor.execute('DELETE FROM %s ' % table) 
      else: 
       prefix = self.make_key(prefix, version) 
       cursor.execute("DELETE FROM %s where cache_key like '%s%%'" % (table, prefix)) 

    global original_clear 
    original_clear = DatabaseCache.clear 
    DatabaseCache.clear = __clear 

patch_clear() 
+0

Djangoは実際にはcache_keyにプレフィックスを付けません。接頭辞が追加されたcache_keyは次のようになります:1:views.decorators.cache.cache_page.prefixname.GET.eb9a021b08e0b96a809a931c0538e9c2.d41d8cd98f00b204e9800998ecf8427e.da-dk.Europe/Copenhagen' 私はあなたのコードを "DELETE FROM {table} cache_keyは '%:1:prefixname%'のようになります " あなたはどうやって取得するのですか?プレフィックスの前の ':1:'を取り除く? – Wessi

+1

':1'を避けるべきである' prefix = self.make_key(prefix、version) 'を自分のコードから削除してください –

2

TLDRを使用しています。 cache.deleteおよびcache.delete_manyをご利用いただけます。

長い答えです。 @cache_pageです。このデコレータを使用すると、キャッシュには常に予想以上に多くのキャッシュエントリが含まれていることがよくあります。あなたは、キャッシュエントリの一束を削除したいと思うことになります。それはまさにここで何が起こったかのようです。

私はデータベースキャッシュを使用していますが、メモリキャッシュは使用していません。

キャッシングを使用する主なアイデアの1つは、高価な計算やdbクエリを減らすために、サーバーの負荷を軽減することです。しかし実際には、多くのWebページには高価な計算がありません。索引を慎重に選択することで、ほとんどの低速問合せを最適化できます。

データベース自体がそのキャッシュである場合、データベースの負荷が軽減されません。ユーザーごとに異なるコンテンツを表示する必要がある場合はどうなりますか?これは非常に複雑です。

key_prefixを含むキーを削除したい場合はどうすればよいですか?

redisを使用することを検討してください。これはdjangoで利用可能な最良のキャッシュバックエンドの1つです(第三者モジュールとして)。 1つのコマンドで複数のキーを削除できることは、レディスの多くの便利な機能の1つです。

関連する問題