1

这个问题困扰了我一上午:

  • 我有一些视图接受 GET 参数来修改查询集(order_by 和分页)并缓存它。
  • 这些视图非常相似,并且都共享相同的模板。
  • 这些模板缓存页面的一部分(考虑到 GET 参数),如下所示:

    {% with order=request.GET.order_by %}{% with page=request.GET.page %}{# I need them to set the cache name #}
    {% cache 7200 template urlname order page %}
    .... some part of the page...
    {% endcache %}
    {% endwith %}{% endwith %}{# with order and with page #}
    
  • 删除查询集缓存是小菜一碟,但事实证明删除模板缓存相当复杂。您通常需要生成 cache_key,如 DOCS 中所述。我的问题是我必须生成所有可能的键组合并删除它们,我这样做是这样的:

    SITE_LIST_OPTIONS = [
        ('url', [reverse_lazy('site_list'),
                 reverse_lazy('best_site_list'),
                 reverse_lazy('banned_site_list'),
                 reverse_lazy('toreview_site_list')]),
        ('order', ['url', 'country', 'upstream_rank']),
        ('page', range(10))]
    
    
    def delete_cache_keys(keys):
        '''Deletes all the cache keys on the provided list.'''
        for e in keys:
            cache.delete(e)
    
    
    def delete_template_cache(key, filters=None):
        # first, we need to get all possible filter combination options
        if filters:
            options = combine_options(filters)
            keys = [make_template_fragment_key(key, ops) for ops in options]
            delete_cache_keys(keys)
        else:
            key = make_template_fragment_key(key, filters)
            cache.delete(key)
    
    # context_processor.py (used to generate key in template)
    
    def urlname(request):
        return {'urlname': resolve_urlname(request)}
    

我想我不是第一个尝试基于 GET 参数缓存模板的人,所以......有没有更明智的方法来删除与这个特定模板相关的所有缓存?

编辑:不知道为什么格式没有出现,但这里有一个更干净的版本,以防万一http://dpaste.org/XYYo2/

4

1 回答 1

0

您可以将模板的所有缓存片段组合在一起,方法是为它们提供绑定到模板的组缓存键。当您想使与模板相关的所有内容失效时,您只需清除模板的组键即可:

>>> from django.core.cache import cache

>>> template_name = 'foo.html'
>>> cache.set(template_name, 1)
>>> make_group_key = lambda: '{name}-{version}'.format(
        name=template_name, version=cache.get(template_name))
>>> cache.set(make_group_key(), 'page content...')
>>> cache.get(make_group_key())
'page content...'

>>> cache.incr(template_name)
>>> cache.get(make_group_key()) is None
True

对于您的代码,您可以编写一个模板标签,将组键传播到上下文,例如

{% get_template_key template as tmpl_key %}
{% cache 7200 template urlname order page tmpl_key %}

或者您可以在视图或其他地方生成密钥。

然后删除部分就像cache.incr(template_name)(您可能需要处理 template_name 不再存在的异常)

这种方法增加了一个额外的缓存往返,但通常它足够快。

于 2013-03-25T14:59:13.133 回答