有没有办法标记缓存的值,以便我可以执行以下操作:
cache.filter('some_tag').clear()
在我的项目中,我有以下模型:
class Item(models.Model):
month = models.DateField('month', null=False, blank=False, db_index=True)
kg = models.BigIntegerField('kg')
tags = models.ManyToManyField('Tag', related_name='items')
// bunch of other fields used to filter data
我有一个report_view
根据提供的kg
按filters
按月和按标记返回总和在URL
查询中。
这样的事情:
--------------------------------
|Tag |jan |fev |mar |
--------------------------------
|Tag 1 |1000 |1500 |2000 |
--------------------------------
|Tag 2 |1235 |4652 |0 |
--------------------------------
由于我的Item
表已有超过400万条记录并且一直在增长,我的report_view
会被缓存。
到目前为止,我完成了所有这些工作。
问题是:网站用户可以从tags
更改Items
,每次发生这种情况我都要使缓存无效,但我想做它采用更多粒度方式。
例如,如果用户更改tag
中的Item
january
,该tag
应该使该月的所有总计无效(我更喜欢按月缓存,因为有时会更改一个URL
1}}对其他人有级联效应)。但是,我不知道所有已缓存的视图,因为有数千种不同的过滤器可能会更改tag
。
到目前为止我做了什么:
cache.filter('some_tag').clear()
更改@receiver(m2m_changed, sender=Item.tags.through) def tags_changed(sender, **kwargs): cache.clear()
但这可以清除一切在我的情况下不是最佳的东西。有没有办法像Django缓存框架那样做pip install cherrypy
?
答案 0 :(得分:2)
https://martinfowler.com/bliki/TwoHardThings.html
计算机科学中只有两件事:缓存失效和命名事物。
- Phil Karlton
假设您使用Django's Cache Middleware,您需要定位相关的缓存键。您可以在Django项目中看到它们如何从这两个文件生成缓存键:
-
https://github.com/django/django/blob/master/django/middleware/cache.py#L99
- https://github.com/django/django/blob/master/django/utils/cache.py#L367
- https://github.com/django/django/blob/master/django/utils/cache.py#L324
def _generate_cache_key(request, method, headerlist, key_prefix):
"""Return a cache key from the headers given in the header list."""
ctx = hashlib.md5()
for header in headerlist:
value = request.META.get(header)
if value is not None:
ctx.update(force_bytes(value))
url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (key_prefix, method, url.hexdigest(), ctx.hexdigest())
return _i18n_cache_key_suffix(request, cache_key)
基于来自请求和散列值的属性和头部生成缓存密钥(即,对URL进行散列并将其用作密钥的一部分)。响应中的Vary
标头指定要用作缓存的一部分的其他标头。
如果您了解Django如何缓存您的视图并计算缓存密钥,那么您可以使用它来定位适当的缓存条目,但这仍然非常困难,因为网址是经过哈希处理的,您无法定位网址模式(你可以使用https://stackoverflow.com/a/35629796/784648 cache.delete_patterns(...)
。
Django主要依靠超时来使缓存失效。
我建议查看Django Cacheops,此软件包旨在与Django的ORM一起使用来缓存和使QuerySet无效。这似乎对您的需求更加实用,因为您希望在Item QuerySet上进行细粒度的失效,而您根本无法从Django的缓存中间件中获得这种失效。看看github repo,我已经使用过它,如果你花时间阅读文档并理解它,它会很好用。