2017-09-26 33 views
3

我使用Django的per-view @cache_page修饰器,并为每个视图设置了不同的key_prefixDjango使用特定的key_prefix删除缓存

我以前删除了与缓存:

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

但如果我只是想删除包含特定key_prefix的钥匙是什么?我明显可以做到这一点,只需连接到数据库并删除原始的SQL,但我想知道是否可以用'纯粹的'Django来完成?

我正在使用数据库缓存,而不是内存缓存。

我使用Django 1.11和Python 3.6

+1

可能重复[从Django缓存中删除所有匹配键](https:// stackoverflow。com/questions/25292426/remove-all-matching-keys-from-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的最好的部分是你可以轻松地猴路径添加新的功能。下面是一个测试请求我创建

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

要获得prefix功能,你需要添加以下代码补丁在某些地方。我用settings.py这样

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看起来像这样':1:views.decorators.cache.cache_page.prefixname.GET.eb9a021b08e0b96a809a931c0538e9c2.d41d8cd98f00b204e9800998ecf8427e.da-dk.Europe/Copenhagen' 我试着将你的代码改为f“DELETE FROM {table}其中cache_key像'%{prefix}%'“,但执行的查询看起来像这样'b'DELETE FROM'cache_table'其中cache_key如'%:1:prefixname%'''' 您是否有任何关于如何获取摆脱前缀前面的':1:'? – Wessi

+1

从我的代码中删除'prefix = self.make_key(前缀,版本)',应该避免使用':1' –

2

TLDR; cache.deletecache.delete_many是您的可用选项。

长的答案。 @cache_page已超额定。当您使用这个装饰器时,您经常会发现缓存总是包含比您预期更多的缓存条目。你最终想要删除一大堆缓存条目。这似乎正是发生在这里的事情。

我正在使用数据库缓存而不是内存缓存。

使用缓存的一个主要思想是减少服务器上的负载,另一个是减少昂贵的计算或db查询。但实际上,很多网页没有昂贵的计算。通过仔细选择索引,可以优化大多数缓慢的查询。

如果数据库本身就是那个缓存,那么就不会减少数据库的负载。如果你需要为不同的用户显示不同的内容呢?这变得非常复杂。

如果我只想删除包含特定 key_prefix的密钥,该怎么办?

考虑使用redis。这是django中最好的缓存后端之一(作为第三方模块)。能够在单个命令中删除多个密钥是redis的许多有用功能之一。

相关问题